8000 Merge pull request #507 from tableau/development · sfarr15/server-client-python@b260ebc · GitHub
[go: up one dir, main page]

Skip to content

Commit b260ebc

Browse files
author
Chris Shin
authored
Merge pull request tableau#507 from tableau/development
Release v0.9 ## 0.9 (4 Oct 2019) * Added Metadata API endpoints (tableau#431) * Added site settings for Data Catalog and Prep Conductor (tableau#434) * Added new fields to ViewItem (tableau#331) * Added support and samples for Tableau Server Personal Access Tokens (tableau#465) * Added Permissions endpoints (tableau#429) * Added tags to ViewItem (tableau#470) * Added Databases and Tables endpoints (tableau#445) * Added Flow endpoints (tableau#494) * Added ability to filter projects by topLevelProject attribute (tableau#497) * Improved server_info endpoint error handling (tableau#439) * Improved Pager to take in keyword arguments (tableau#451) * Fixed UUID serialization error while publishing workbook (tableau#449) * Fixed materalized views in request body for update_workbook (tableau#461)
2 parents 2c2ce91 + fe3ac07 commit b260ebc

Some content is hidden

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

72 files changed

+2771
-71
lines changed

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1+
dist: xenial
12
language: python
23
python:
34
- "2.7"
45
- "3.5"
56
- "3.6"
6-
- "pypy"
7+
- "3.7"
78
# command to install dependencies
89
install:
910
- "pip install -e ."
@@ -12,5 +13,4 @@ install:
1213
script:
1314
# Tests
1415
- python setup.py test
15-
# pep8 - disabled for now until we can scrub the files to make sure we pass before turning it on
1616
- pycodestyle tableauserverclient test samples

CHANGELOG.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
## 0.9 (4 Oct 2019)
2+
3+
* Added Metadata API endpoints (#431)
4+
* Added site settings for Data Catalog and Prep Conductor (#434)
5+
* Added new fields to ViewItem (#331)
6+
* Added support and samples for Tableau Server Personal Access Tokens (#465)
7+
* Added Permissions endpoints (#429)
8+
* Added tags to ViewItem (#470)
9+
* Added Databases and Tables endpoints (#445)
10+
* Added Flow endpoints (#494)
11+
* Added ability to filter projects by topLevelProject attribute (#497)
12+
* Improved server_info endpoint error handling (#439)
13+
* Improved Pager to take in keyword arguments (#451)
14+
* Fixed UUID serialization error while publishing workbook (#449)
15+
* Fixed materalized views in request body for update_workbook (#461)
16+
117
## 0.8.1 (17 July 2019)
218

319
* Fixed update_workbook endpoint (#454)
@@ -13,7 +29,6 @@
1329
* Fixed checked upload (#309, #319, #326, #329)
1430
* Fixed embed_password field on publish (#416)
1531

16-
1732
## 0.7 (2 Jul 2018)
1833

1934
* Added cancel job (#299)

CONTRIBUTORS.md

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,26 @@ The following people have contributed to this project to make it possible, and w
1919
* [Bruce Zhang](https://github.com/baixin137)
2020
* [Bumsoo Kim](https://github.com/bskim45)
2121
* [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)
2231

2332
## Core Team
2433

25-
* [Shin Chris](https://github.com/shinchris)
34+
* [Chris Shin](https://github.com/shinchris)
2635
* [Lee Graber](https://github.com/lgraber)
2736
* [Tyler Doyle](https://github.com/t8y8)
2837
* [Russell Hay](https://github.com/RussTheAerialist)
2938
* [Ben Lower](https://github.com/benlower)
30-
* [Jared Dominguez](https://github.com/jdomingu)
3139
* [Jackson Huang](https://github.com/jz-huang)
32-
* [Brendan Lee](https://github.com/lbrendanl)
3340
* [Ang Gao](https://github.com/gaoang2148)
34-
* [Priya R](https://github.com/preguraman)
41+
* [Priya Reguraman](https://github.com/preguraman)
42+
* [Jac Fitzgerald](https://github.com/jacalata)
43+
* [Dan Zucker](https://github.com/dzucker-tab)
44+
* [Irwin Dolobowsky](https://github.com/irwando)

samples/login.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
####
2+
# This script demonstrates how to log in to Tableau Server Client.
3+
#
4+
# To run the script, you must have installed Python 2.7.9 or later.
5+
####
6+
7+
import argparse
8+
import getpass
9+
import logging
10+
11+
import tableauserverclient as TSC
12+
13+
14+
def main():
15+
parser = argparse.ArgumentParser(description='Logs in to the server.')
16+
17+
parser.add_argument('--logging-level', '-l', choices=['debug', 'info', 'error'], default='error',
18+
help='desired logging level (set to error by default)')
19+
20+
parser.add_argument('--server', '-s', required=True, help='server address')
21+
22+
group = parser.add_mutually_exclusive_group(required=True)
23+
group.add_argument('--username', '-u', help='username to sign into the server')
24+
group.add_argument('--token-name', '-n', help='name of the personal access token used to sign into the server')
25+
26+
args = parser.parse_args()
27+
28+
# Set logging level based on user input, or error by default.
29+
logging_level = getattr(logging, args.logging_level.upper())
30+
logging.basicConfig(level=logging_level)
31+
32+
# Make sure we use an updated version of the rest apis.
33+
server = TSC.Server(args.server, use_server_version=True)
34+
35+
if args.username:
36+
# Trying to authenticate using username and password.
37+
password = getpass.getpass("Password: ")
38+
tableau_auth = TSC.TableauAuth(args.username, password)
39+
with server.auth.sign_in(tableau_auth):
40+
print('Logged in successfully')
41+
42+
else:
43+
# Trying to authenticate using personal access tokens.
44+
personal_access_token = getpass.getpass("Personal Access Token: ")
45+
tableau_auth = TSC.PersonalAccessTokenAuth(token_name=args.token_name,
46+
personal_access_token=personal_access_token)
47+
with server.auth.sign_in_with_personal_access_token(tableau_auth):
48+
print('Logged in successfully')
49+
50+
51+
if __name__ == '__main__':
52+
main()

setup.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1+
import sys
12
import versioneer
3+
24
try:
35
from setuptools import setup
46
except ImportError:
57
from distutils.core import setup
68

9+
# Only install pytest and runner when test command is run
10+
# This makes work easier for offline installs or low bandwidth machines
11+
needs_pytest = {'pytest', 'test', 'ptr'}.intersection(sys.argv)
12+
pytest_runner = ['pytest-runner'] if needs_pytest else []
13+
714
setup(
815
name='tableauserverclient',
916
version=versioneer.get_version(),
@@ -16,11 +23,10 @@
1623
license='MIT',
1724
description='A Python module for working with the Tableau Server REST API.',
1825
test_suite='test',
19-
setup_requires=[
20-
'pytest-runner'
21-
],
26+
setup_requires=pytest_runner,
2227
install_requires=[
23-
'requests>=2.11,<3.0'
28+
'requests>=2.11,<3.0',
29+
'urllib3==1.24.3'
2430
],
2531
tests_require=[
2632
'requests-mock>=1.0,<2.0',

tableauserverclient/__init__.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
from .namespace import NEW_NAMESPACE as DEFAULT_NAMESPACE
22
from .models import ConnectionCredentials, ConnectionItem, DatasourceItem,\
3-
GroupItem, JobItem, BackgroundJobItem, PaginationItem, ProjectItem, ScheduleItem, \
4-
SiteItem, TableauAuth, UserItem, ViewItem, WorkbookItem, UnpopulatedPropertyError, \
5-
HourlyInterval, DailyInterval, WeeklyInterval, MonthlyInterval, IntervalItem, TaskItem, \
6-
SubscriptionItem, Target
3+
GroupItem, JobItem, BackgroundJobItem, PaginationItem, ProjectItem, ScheduleItem,\
4+
SiteItem, TableauAuth, PersonalAccessTokenAuth, UserItem, ViewItem, WorkbookItem, UnpopulatedPropertyError,\
5+
HourlyInterval, DailyInterval, WeeklyInterval, MonthlyInterval, IntervalItem, TaskItem,\
6+
SubscriptionItem, Target, PermissionsRule, Permission, DatabaseItem, TableItem, ColumnItem, FlowItem
77
from .server import RequestOptions, CSVRequestOptions, ImageRequestOptions, PDFRequestOptions, Filter, Sort, \
88
Server, ServerResponseError, MissingRequiredFieldError, NotSignedInError, Pager
99
from ._version import get_versions

tableauserverclient/models/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
from .connection_credentials import ConnectionCredentials
22
from .connection_item import ConnectionItem
3+
from .column_item import ColumnItem
34
from .datasource_item import DatasourceItem
5+
from .database_item import DatabaseItem
46
from .exceptions import UnpopulatedPropertyError
57
from .group_item import GroupItem
8+
from .flow_item import FlowItem
69
from .interval_item import IntervalItem, DailyInterval, WeeklyInterval, MonthlyInterval, HourlyInterval
710
from .job_item import JobItem, BackgroundJobItem
811
from .pagination_item import PaginationItem
@@ -11,9 +14,12 @@
1114
from .server_info_item import ServerInfoItem
1215
from .site_item import SiteItem
1316
from .tableau_auth import TableauAuth
17+
from .personal_access_token_auth import PersonalAccessTokenAuth
1418
from .target import Target
19+
from .table_item import TableItem
1520
from .task_item import TaskItem
1621
from .user_item import UserItem
1722
from .view_item import ViewItem
1823
from .workbook_item import WorkbookItem
1924
from .subscription_item import SubscriptionItem
25+
from .permissions_item import PermissionsRule, Permission
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import xml.etree.ElementTree as ET
2+
3+
from .property_decorators import property_is_enum, property_not_empty
4+
from .exceptions import UnpopulatedPropertyError
5+
6+
7+
class ColumnItem(object):
8+
def __init__(self, name, description=None):
9+
self._id = None
10+
self.description = description
11+
self.name = name
12+
13+
@property
14+
def id(self):
15+
return self._id
16+
17+
@property
18+
def name(self):
19+
return self._name
20+
21+
@name.setter
22+
@property_not_empty
23+
def name(self, value):
24+
self._name = value
25+
26+
@property
27+
def description(self):
28+
return self._description
29+
30+
@description.setter
31+
def description(self, value):
32+
self._description = value
33+
34+
@property
35+
def remote_type(self):
36+
return self._remote_type
37+
38+
def _set_values(self, id, name, description, remote_type):
39+
if id is not None:
40+
self._id = id
41+
if name:
42+
self._name = name
43+
if description:
44+
self.description = description
45+
if remote_type:
46+
self._remote_type = remote_type
47+
48+
@classmethod
49+
def from_response(cls, resp, ns):
50+
all_column_items = list()
51+
parsed_response = ET.fromstring(resp)
52+
all_column_xml = parsed_response.findall('.//t:column', namespaces=ns)
53+
54+
for column_xml in all_column_xml:
55+
(id, name, description, remote_type) = cls._parse_element(column_xml, ns)
56+
column_item = cls(name)
57+
column_item._set_values(id, name, description, remote_type)
58+
all_column_items.append(column_item)
59+
60+
return all_column_items
61+
62+
@staticmethod
63+
def _parse_element(column_xml, ns):
64+
id = column_xml.get('id', None)
65+
name = column_xml.get('name', None)
66+
description = column_xml.get('description', None)
67+
remote_type = column_xml.get('remoteType', None)
68+
69+
return id, name, description, remote_type

0 commit comments

Comments
 (0)
0