8000 Development to master for v0.12 (#646) · rshide/server-client-python@6ef56aa · GitHub
[go: up one dir, main page]

Skip to content

Commit 6ef56aa

Browse files
Chris ShinjacalataReba Magierscumlmbren
authored
Development to master for v0.12 (tableau#646)
* Sync development with master branch (tableau#613) * delete docs folder from master (tableau#520) * delete folder * add back readme for docs * Fix logger statement in User.add (tableau#608) The logger statement is using the parameter to output the id of the user, but that isnt set until line 67 and saved to a new variable. We want the logger statement to use that new user Co-authored-by: Jac <jacalata@users.noreply.github.com> Co-authored-by: Reba Magier <rebeccam@syapse.com> * Adds hidden_views parameter to publish() (tableau#614) * delete docs folder from master (tableau#520) * delete folder * add back readme for docs * Fix logger statement in User.add (tableau#608) The logger statement is using the parameter to output the id of the user, but that isnt set until line 67 and saved to a new variable. We want the logger statement to use that new user * Adds hidden views parameter to workbook publish * Pycodestyle Co-authored-by: Chris Shin <cshin@tableau.com> Co-authored-by: Jac <jacalata@users.noreply.github.com> Co-authored-by: Reba Magier <rebeccam@syapse.com> * Code cleanup (tableau#618) * delete docs folder from master (tableau#520) * delete folder * add back readme for docs * Fix logger statement in User.add (tableau#608) The logger statement is using the parameter to output the id of the user, but that isnt set until line 67 and saved to a new variable. We want the logger statement to use that new user * Cleans up imports and fixes some errors along the way * pycodestyle fix for single char var name Co-authored-by: Chris Shin <cshin@tableau.com> Co-authored-by: Jac <jacalata@users.noreply.github.com> Co-authored-by: Reba Magier <rebeccam@syapse.com> * update comment to say Python 3.5 is required to run samples (tableau#619) * update comment to say Python 3.5 is required to run samples * pycodestyle fix for single char var name * Simple Paging Endpoint for GraphQL/Metadata API (tableau#623) Because GraphQL can be arbitrarily complex and nested, we can't get as smart with an automatic Pager object without parsing the query, and that's a can of worms. So for now, I added a new endpoint that will take a single query with one set of pagination parameters and run through it until it ends. It's not very smart, but it works. * Support Metadata Services Backfill & Eventing APIs (tableau#626) Simple JSON endpoints that return the status of Metadata Services related events. * Adds in maxage param to csv and pdf export options (tableau#635) * Adds in maxage param to csv and pdf export options * Fixes style issue * Adding named param to test to be clear * User favorites endpoint (tableau#638) * Create FavoriteRequest factory * Create favorites_endpoint * Enable addition of favorites * Enabled deletion of favorites * Fix XML response calls * Genericize descriptor * Fix typo * Remove outdated content * Use more descriptive variable names * Adjust API version * Create Favorite "enum" * Factor response parsing logic to model The favorites item is now a dictionary. The user_item has been altered to reflect this. * Test favorites.get * Test adding a favorite workbook * Test adding favorite view * Test adding favorite data source * Test adding favorite project * Test favorite deletion * Expand favorites test_get * Unpack list of views in class method response * Add Favorites back to import * Replace deprecated assertEquals with assertEqual * Rename Favorite FavoriteItem and encapsulate Co-authored-by: Woods <jordan.woods@mkcorp.com> * Fixing style error * Fixes maxage to allow 0 as input (tableau#639) * Adds a sample for publishing datasources (tableau#644) * Adds a sample for publishing datasources * Addresses feedback to use PAT and async flag * Prep for v0.12 (tableau#645) * delete docs folder from master (tableau#520) * delete folder * add back readme for docs * Fix logger statement in User.add (tableau#608) The logger statement is using the parameter to output the id of the user, but that isnt set until line 67 and saved to a new variable. We want the logger statement to use that new user * Prepares v0.12 release * Fixes typo in changelog Co-authored-by: Jac <jacalata@users.noreply.github.com> Co-authored-by: Reba Magier <rebeccam@syapse.com> Co-authored-by: Jac <jacalata@users.noreply.github.com> Co-authored-by: Reba Magier <rebeccam@syapse.com> Co-authored-by: Stephen Mitchell <scum@mac.com> Co-authored-by: Mary Brennan <mbren@users.noreply.github.com> Co-authored-by: Tyler Doyle <kingt8y8@gmail.com> Co-authored-by: jorwoods <jorwoods@users.noreply.github.com> Co-authored-by: Woods <jordan.woods@mkcorp.com>
1 parent 188be71 commit 6ef56aa

File tree

80 files changed

+913
-120
lines changed

Some content is hidden

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

80 files changed

+913
-120
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
## 0.12 (10 July 2020)
2+
3+
* Added hidden_views parameter to workbook publish method (#614)
4+
* Added simple paging endpoint for GraphQL/Metadata API (#623)
5+
* Added endpoints to Metadata API for retrieving backfill/eventing status (#626)
6+
* Added maxage parameter to CSV and PDF export options (#635)
7+
* Added support for querying, adding, and deleting favorites (#638)
8+
* Added a sample for publishing datasources (#644)
9+
110
## 0.11 (1 May 2020)
211

312
* Added more fields to Data Acceleration config (#588)

CONTRIBUTORS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ The following people have contributed to this project to make it possible, and w
3636
* [Geraldine Zanolli](https://github.com/illonage)
3737
* [Jordan Woods](https://github.com/jorwoods)
3838
* [Reba Magier](https://github.com/rmagier1)
39+
* [Stephen Mitchell](https://github.com/scuml)
3940

4041
## Core Team
4142

samples/create_group.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# This script demonstrates how to create groups using the Tableau
33
# Server Client.
44
#
5-
# To run the script, you must have installed Python 2.7.9 or later.
5+
# To run the script, you must have installed Python 3.5 or later.
66
####
77

88

samples/create_project.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# parent_id.
55
#
66
#
7-
# To run the script, you must have installed Python 2.7.X or 3.3 and later.
7+
# To run the script, you must have installed Python 3.5 or later.
88
####
99

1010
import argparse

samples/create_schedules.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# This script demonstrates how to create schedules using the Tableau
33
# Server Client.
44
#
5-
# To run the script, you must have installed Python 2.7.9 or later.
5+
# To run the script, you must have installed Python 3.5 or later.
66
####
77

88

samples/download_view_image.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# For more information, refer to the documentations on 'Query View Image'
66
# (https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm)
77
#
8-
# To run the script, you must have installed Python 2.7.X or 3.3 and later.
8+
# To run the script, you must have installed Python 3.5 or later.
99
####
1010

1111
import argparse

samples/filter_sort_groups.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# This script demonstrates how to filter groups using the Tableau
33
# Server Client.
44
#
5-
# To run the script, you must have installed Python 2.7.9 or later.
5+
# To run the script, you must have installed Python 3.5 or later.
66
####
77

88

samples/filter_sort_projects.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# to filter and sort on the name of the projects present on site.
44
#
55
#
6-
# To run the script, you must have installed Python 2.7.X or 3.3 and later.
6+
# To run the script, you must have installed Python 3.5 or later.
77
####
88

99
import argparse

samples/kill_all_jobs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
####
22
# This script demonstrates how to kill all of the running jobs
33
#
4-
# To run the script, you must have installed Python 2.7.X or 3.3 and later.
4+
# To run the script, you must have installed Python 3.5 or later.
55
####
66

77
import argparse

samples/list.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
####
22
# This script demonstrates how to list all of the workbooks or datasources
33
#
4-
# To run the script, you must have installed Python 2.7.X or 3.3 and later.
4+
# To run the script, you must have installed Python 3.5 or later.
55
####
66

77
import argparse

samples/login.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
####
22
# This script demonstrates how to log in to Tableau Server Client.
33
#
4-
# To run the script, you must have installed Python 2.7.9 or later.
4+
# To run the script, you must have installed Python 3.5 or later.
55
####
66

77
import argparse

samples/move_workbook_projects.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# a workbook that matches a given name and update it to be in
55
# the desired project.
66
#
7-
# To run the script, you must have installed Python 2.7.X or 3.3 and later.
7+
# To run the script, you must have installed Python 3.5 or later.
88
####
99

1010
import argparse

samples/move_workbook_sites.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# a workbook that matches a given name, download the workbook,
55
# and then publish it to the destination site.
66
#
7-
# To run the script, you must have installed Python 2.7.X or 3.3 and later.
7+
# To run the script, you must have installed Python 3.5 or later.
88
####
99

1010
import argparse

samples/publish_datasource.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
####
2+
# This script demonstrates how to use the Tableau Server Client
3+
# to publish a datasource to a Tableau server. It will publish
4+
# a specified datasource to the 'default' project of the provided site.
5+
#
6+
# Some optional arguments are provided to demonstrate async publishing,
7+
# as well as providing connection credentials when publishing. If the
8+
# provided datasource file is over 64MB in size, TSC will automatically
9+
# publish the datasource using the chunking method.
10+
#
11+
# For more information, refer to the documentations:
12+
# (https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_datasources.htm#publish_data_source)
13+
#
14+
# For signing into server, this script uses personal access tokens. For
15+
# more information on personal access tokens, refer to the documentations:
16+
# (https://help.tableau.com/current/server/en-us/security_personal_access_tokens.htm)
17+
#
18+
# To run the script, you must have installed Python 3.5 or later.
19+
####
20+
21+
import argparse
22+
import logging
23+
24+
import tableauserverclient as TSC
25+
26+
27+
def main():
28+
parser = argparse.ArgumentParser(description='Publish a datasource to server.')
29+
parser.add_argument('--server', '-s', required=True, help='server address')
30+
parser.add_argument('--site', '-i', help='site name')
31+
parser.add_argument('--token-name', '-p', required=True,
32+
help='name of the personal access token used to sign into the server')
33+
parser.add_argument('--token-value', '-v', required=True,
34+
help='value of the personal access token used to sign into the server')
35+
parser.add_argument('--filepath', '-f', required=True, help='filepath to the datasource to publish')
36+
parser.add_argument('--logging-level', '-l', choices=['debug', 'info', 'error'], default='error',
37+
help='desired logging level (set to error by default)')
38+
parser.add_argument('--async', '-a', help='Publishing asynchronously', dest='async_', action='store_true')
39+
parser.add_argument('--conn-username', help='connection username')
40+
parser.add_argument('--conn-password', help='connection password')
41+
parser.add_argument('--conn-embed', help='embed connection password to datasource', action='store_true')
42+
parser.add_argument('--conn-oauth', help='connection is configured to use oAuth', action='store_true')
43+
44+
args = parser.parse_args()
45+
46+
# Ensure that both the connection username and password are provided, or none at all
47+
if (args.conn_username and not args.conn_password) or (not args.conn_username and args.conn_password):
48+
parser.error("Both the connection username and password must be provided")
49+
50+
# Set logging level based on user input, or error by default
51+
logging_level = getattr(logging, args.logging_level.upper())
52+
logging.basicConfig(level=logging_level)
53+
54+
# Sign in to server
55+
tableau_auth = TSC.PersonalAccessTokenAuth(args.token_name, args.token_value, site_id=args.site)
56+
server = TSC.Server(args.server, use_server_version=True)
57+
with server.auth.sign_in(tableau_auth):
58+
# Create a new datasource item to publish - empty project_id field
59+
# will default the publish to the site's default project
60+
new_datasource = TSC.DatasourceItem(project_id="")
61+
62+
# Create a connection_credentials item if connection details are provided
63+
new_conn_creds = None
64+
if args.conn_username:
65+
new_conn_creds = TSC.ConnectionCredentials(args.conn_username, args.conn_password,
66+
embed=args.conn_embed, oauth=args.conn_oauth)
67+
68+
# Define publish mode - Overwrite, Append, or CreateNew
69+
publish_mode = TSC.Server.PublishMode.Overwrite
70+
71+
# Publish datasource
72+
if args.async_:
73+
# Async publishing, returns a job_item
74+
new_job = server.datasources.publish(new_datasource, args.filepath, publish_mode,
75+
connection_credentials=new_conn_creds, as_job=True)
76+
print("Datasource published asynchronously. Job ID: {0}".format(new_job.id))
77+
else:
78+
# Normal publishing, returns a datasource_item
79+
new_datasource = server.datasources.publish(new_datasource, args.filepath, publish_mode,
80+
connection_credentials=new_conn_creds)
81+
print("Datasource published. Datasource ID: {0}".format(new_datasource.id))
82+
83+
84+
if __name__ == '__main__':
85+
main()

samples/publish_workbook.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
# For more information, refer to the documentations on 'Publish Workbook'
1212
# (https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm)
1313
#
14-
# To run the script, you must have installed Python 2.7.X or 3.3 and later.
14+
# To run the script, you must have installed Python 3.5 or later.
1515
####
1616

1717
import argparse

samples/refresh.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
####
22
# This script demonstrates how to use trigger a refresh on a datasource or workbook
33
#
4-
# To run the script, you must have installed Python 2.7.X or 3.3 and later.
4+
# To run the script, you must have installed Python 3.5 or later.
55
####
66

77
import argparse

samples/refresh_tasks.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# This script demonstrates how to use the Tableau Server Client
33
# to query extract refresh tasks and run them as needed.
44
#
5-
# To run the script, you must have installed Python 2.7.X or 3.3 and later.
5+
# To run the script, you must have installed Python 3.5 or later.
66
####
77

88
import argparse

samples/set_http_options.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# This script demonstrates how to set http options. It will set the option
33
# to not verify SSL certificate, and query all workbooks on site.
44
#
5-
# To run the script, you must have installed Python 2.7.X or 3.3 and later.
5+
# To run the script, you must have installed Python 3.5 or later.
66
####
77

88
import argparse

samples/update_connection.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
####
22
# This script demonstrates how to update a connections credentials on a server to embed the credentials
33
#
4-
# To run the script, you must have installed Python 2.7.X or 3.3 and later.
4+
# To run the script, you must have installed Python 3.5 or later.
55
####
66

77
import argparse

tableauserverclient/datetime_helpers.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import datetime
22

3-
# This code below is from the python documentation for tzinfo: https://docs.python.org/2.3/lib/datetime-tzinfo.html
3+
# This code below is from the python documentation for
4+
# tzinfo: https://docs.python.org/2.3/lib/datetime-tzinfo.html
5+
46
ZERO = datetime.timedelta(0)
57
HOUR = datetime.timedelta(hours=1)
68

tableauserverclient/models/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from .datasource_item import DatasourceItem
66
from .database_item import DatabaseItem
77
from .exceptions import UnpopulatedPropertyError
8+
from .favorites_item import FavoriteItem
89
from .group_item import GroupItem
910
from .flow_item import FlowItem
1011
from .interval_item import IntervalItem, DailyInterval, WeeklyInterval, MonthlyInterval, HourlyInterval

tableauserverclient/models/column_item.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import xml.etree.ElementTree as ET
22

3-
from .property_decorators import property_is_enum, property_not_empty
4-
from .exceptions import UnpopulatedPropertyError
3+
from .property_decorators import property_not_empty
54

65

76
class ColumnItem(object):

tableauserverclient/models/connection_item.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,10 @@ def connection_type(self):
3232
return self._connection_type
3333

3434
def __repr__(self):
35-
return "<ConnectionItem#{_id} embed={embed_password} type={_connection_type} username={username}>"\
36-
.format(**self.__dict__)
35+
return (
36+
"<ConnectionItem#{_id} embed={embed_password} "
37+
"type={_connection_type} username={username}>".format(**self.__dict__)
38+
)
3739

3840
@classmethod
3941
def from_response(cls, resp, ns):
@@ -76,11 +78,13 @@ def from_xml_element(cls, parsed_response, ns):
7678
connection_item.server_address = connection_xml.get('serverAddress', None)
7779
connection_item.server_port = connection_xml.get('serverPort', None)
7880

79-
connection_credentials = connection_xml.find('.//t:connectionCredentials', namespaces=ns)
81+
connection_credentials = connection_xml.find(
82+
'.//t:connectionCredentials', namespaces=ns)
8083

8184
if connection_credentials is not None:
8285

83-
connection_item.connection_credentials = ConnectionCredentials.from_xml_element(connection_credentials)
86+
connection_item.connection_credentials = ConnectionCredentials.from_xml_element(
87+
connection_credentials)
8488

8589
return all_connection_items
8690

tableauserverclient/models/data_acceleration_report_item.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,6 @@ def site(self):
2121
def sheet_uri(self):
2222
return self._sheet_uri
2323

24-
@property
25-
def site(self):
26-
return self._site
27-
2824
@property
2925
def unaccelerated_session_count(self):
3026
return self._unaccelerated_session_count

tableauserverclient/models/database_item.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import xml.etree.ElementTree as ET
22

3-
from .permissions_item import Permission
4-
53
from .property_decorators import property_is_enum, property_not_empty, property_is_boolean
64
from .exceptions import UnpopulatedPropertyError
75

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import xml.etree.ElementTree as ET
2+
import logging
3+
from .workbook_item import WorkbookItem
4+
from .view_item import ViewItem
5+
from .project_item import ProjectItem
6+
from .datasource_item import DatasourceItem
7+
8+
logger = logging.getLogger('tableau.models.favorites_item')
9+
10+
11+
class FavoriteItem:
12+
class Type:
13+
Workbook = 'workbook'
14+
Datasource = 'datasource'
15+
View = 'view'
16+
Project = 'project'
17+
18+
@classmethod
19+
def from_response(cls, xml, namespace):
20+
favorites = {
21+
'datasources': [],
22+
'projects': [],
23+
'views': [],
24+
'workbooks': [],
25+
}
26+
27+
parsed_response = ET.fromstring(xml)
28+
for workbook in parsed_response.findall('.//t:favorite/t:workbook', namespace):
29+
fav_workbook = WorkbookItem('')
30+
fav_workbook._set_values(*fav_workbook._parse_element(workbook, namespace))
31+
if fav_workbook:
32+
favorites['workbooks'].append(fav_workbook)
33+
for view in parsed_response.findall('.//t:favorite[t:view]', namespace):
34+
fav_views = ViewItem.from_xml_element(view, namespace)
35+
if fav_views:
36+
for fav_view in fav_views:
37+
favorites['views'].append(fav_view)
38+
for datasource in parsed_response.findall('.//t:favorite/t:datasource', namespace):
39+
fav_datasource = DatasourceItem('')
40+
fav_datasource._set_values(*fav_datasource._parse_element(datasource, namespace))
41+
if fav_datasource:
42+
favorites['datasources'].append(fav_datasource)
43+
for project in parsed_response.findall('.//t:favorite/t:project', namespace):
44+
fav_project = ProjectItem('p')
45+
fav_project._set_values(*fav_project._parse_element(project))
46+
if fav_project:
47+
favorites['projects'].append(fav_project)
48+
49+
return favorites

tableauserverclient/models/flow_item.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import xml.etree.ElementTree as ET
22
from .exceptions import UnpopulatedPropertyError
3-
from .property_decorators import property_not_nullable, property_is_boolean
3+
from .property_decorators import property_not_nullable
44
from .tag_item import TagItem
55
from ..datetime_helpers import parse_datetime
66
import copy

tableauserverclient/models/interval_item.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ def interval(self, interval_value):
173173
try:
174174
if not (1 <= int(interval_value) <= 31):
175175
raise ValueError(error)
176-
except ValueError as e:
176+
except ValueError:
177177
if interval_value != "LastDay":
178178
raise ValueError(error)
179179

0 commit comments

Comments
 (0)
0