Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
de61f87
fixed publish mode enums and typos in samples
shinchris Sep 16, 2016
b61f421
Merge pull request #35 from tableau/bugfix-sample-enum
shinchris Sep 16, 2016
4c7a467
Updated all _construct_url() to just @property baseurl
LGraber Sep 27, 2016
36d63c0
Fixed pep8 issue (extra empty line)
LGraber Sep 27, 2016
e9aa592
Add property decorators
LGraber Sep 28, 2016
6897738
Add decorator files
LGraber Sep 28, 2016
1a0b945
Add test cases and combine decorators into one file
Sep 29, 2016
5ead147
Remove * and be explicit on imports
LGraber Sep 29, 2016
48a5f49
Ignore PyCharm related files
LGraber Sep 29, 2016
8c17ecc
Fix Travis errors. Fix error text for property_not_empty
LGraber Sep 29, 2016
05ff9fd
Trying again to fix travis complaints
LGraber Sep 29, 2016
a13d708
Rename property decorators
LGraber Sep 30, 2016
56af4af
Merge pull request #46 from tableau/issue-38
LGraber Sep 30, 2016
ab6b664
Cleaning up samples (#47)
t8y8 Oct 2, 2016
5dbdbee
Adding Schedules Support (#48)
t8y8 Oct 7, 2016
6da2cbe
Minor cleanups in __init__ and ScheduleItem serializer, and a flake8 …
t8y8 Oct 11, 2016
03d26cd
Fix for issue #60 (#61)
t8y8 Oct 15, 2016
4f4112b
Fix for issue #50 Add regex validator to content_url (#64)
t8y8 Oct 18, 2016
02559ab
Making the user list operations a no-op if we haven't populated the l…
Oct 20, 2016
eb91b41
Bugfix 66 add create group basic (#69)
Oct 20, 2016
4b9a86a
merging master into development
Oct 25, 2016
fd59034
Adding contributing doc that was missing from the repo (#74)
Oct 25, 2016
5ac17ec
Pipe password through to Update User (#75)
t8y8 Oct 25, 2016
e1f38a8
Update TableauAuth to speak in site_id rather than just site (#70)
Oct 27, 2016
2f041d1
Add Guest to site role enum (#83)
Kovner Oct 27, 2016
7c41a0a
Add connection credentials (#80)
geordielad Oct 27, 2016
1cbc230
Adding pagination sample (#72)
Oct 28, 2016
a6975db
Implement get server info (#84)
Oct 28, 2016
a4b90ca
Prep version 0.2 (#86)
Oct 28, 2016
6a48ddc
Cleanup duplications (#87)
Oct 28, 2016
101eedb
Fix missing token on requests (#89)
t8y8 Oct 31, 2016
a6d0ede
Implement Pager for auto-paging requests (#90)
t8y8 Oct 31, 2016
b6b0834
Adding changelog for release
Nov 1, 2016
1417564
Incorporating Tyler's feedback
Nov 1, 2016
ee4b36a
oops, scratch that, reverse it: site_id is the right one
Nov 1, 2016
79e9a2a
Merge pull request #92 from tableau/prep-for-0-2
Nov 1, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ docs/_build/
# PyBuilder
target/

# PyCharm stuff
.idea/

# IPython Notebook
.ipynb_checkpoints

Expand Down
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
## 0.2 (02 November 2016)

* Added Initial Schedules Support (#48)
* Added Initial Create Group endpoint (#69)
* Added Connection Credentials for publishing datasources/workbooks (#80)
* Added Pager object for handling pagination results and sample (#72, #90)
* Added ServerInfo endpoint (#84)
* Deprecated `site` as a parameter to `TableauAuth` in favor of `site_id`
* Code Cleanup
* Bugfixes

## 0.1 (12 September 2016)

* Initial Release to the world
16 changes: 16 additions & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
This project wouldn't be possible without our amazing contributors.

The following people have contributed to this project to make it possible, and we thank them for their contributions!

## Contributors

* [geordielad](https://github.com/geordielad)
* [kovner](https://github.com/kovner)


## Core Team

* [shinchris](https://github.com/shinchris)
* [lgraber](https://github.com/lgraber)
* [t8y8](https://github.com/t8y8)
* [RussTheAerialist](https://github.com/RussTheAerialist)
55 changes: 55 additions & 0 deletions contributing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Contributing

We welcome contributions to this project!

Contribution can include, but are not limited to, any of the following:

* File an Issue
* Request a Feature
* Implement a Requested Feature
* Fix an Issue/Bug
* Add/Fix documentation

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.

## Issues and Feature Requests

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.

If you are submitting a bug report, please provide as much information as you can, including clear and concise repro steps, attaching any necessary
files to assist in the repro. **Be sure to scrub the files of any potentially sensitive information. Issues are public.**

For a feature request, please try to describe the scenario you are trying to accomplish that requires the feature. This will help us understand
the limitations that you are running into, and provide us with a use case to know if we've satisfied your request.

### Label usage on Issues

The core team is responsible for assigning most labels to the issue. Labels
are used for prioritizing the core team's work, and use the following
definitions for labels.

The following labels are only to be set or changed by the core team:

* **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.
* **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.
* **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
* **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.
* **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.

The following labels can be used by the issue creator or anyone in the
community to help us prioritize enhancement and bug fixes that are
causing pain from our users. The short of it is, purple tags are ones that
anyone can add to an issue:

* **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.
* **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.

## Fixes, Implementations, and Documentation

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
creating a PR can be found in the [github documentation](https://help.github.com/articles/creating-a-pull-request/)

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
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
somewhere.
42 changes: 42 additions & 0 deletions samples/create_group.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
####
# This script demonstrates how to create groups using the Tableau
# Server Client.
#
# To run the script, you must have installed Python 2.7.9 or later.
####


import argparse
import getpass
import logging

from datetime import time

import tableauserverclient as TSC


def main():

parser = argparse.ArgumentParser(description='Creates sample schedules for each type of frequency.')
parser.add_argument('--server', '-s', required=True, help='server address')
parser.add_argument('--username', '-u', required=True, help='username to sign into server')
parser.add_argument('--logging-level', '-l', choices=['debug', 'info', 'error'], default='error',
help='desired logging level (set to error by default)')
args = parser.parse_args()

password = getpass.getpass("Password: ")

# Set logging level based on user input, or error by default
logging_level = getattr(logging, args.logging_level.upper())
logging.basicConfig(level=logging_level)

tableau_auth = TSC.TableauAuth(args.username, password)
server = TSC.Server(args.server)
with server.auth.sign_in(tableau_auth):
group = TSC.GroupItem('test')
group = server.groups.create(group)
print(group)


if __name__ == '__main__':
main()
77 changes: 77 additions & 0 deletions samples/create_schedules.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
####
# This script demonstrates how to create schedules using the Tableau
# Server Client.
#
# To run the script, you must have installed Python 2.7.9 or later.
####


import argparse
import getpass
import logging

from datetime import time

import tableauserverclient as TSC


def main():

parser = argparse.ArgumentParser(description='Creates sample schedules for each type of frequency.')
parser.add_argument('--server', '-s', required=True, help='server address')
parser.add_argument('--username', '-u', required=True, help='username to sign into server')
parser.add_argument('--logging-level', '-l', choices=['debug', 'info', 'error'], default='error',
help='desired logging level (set to error by default)')
args = parser.parse_args()

password = getpass.getpass("Password: ")

# Set logging level based on user input, or error by default
logging_level = getattr(logging, args.logging_level.upper())
logging.basicConfig(level=logging_level)

tableau_auth = TSC.TableauAuth(args.username, password)
server = TSC.Server(args.server)
with server.auth.sign_in(tableau_auth):
# Hourly Schedule
# This schedule will run every 2 hours between 2:30AM and 11:00PM
hourly_interval = TSC.HourlyInterval(start_time=time(2, 30),
end_time=time(23, 0),
interval_value=2)

hourly_schedule = TSC.ScheduleItem("Hourly-Schedule", 50, TSC.ScheduleItem.Type.Extract,
TSC.ScheduleItem.ExecutionOrder.Parallel, hourly_interval)
hourly_schedule = server.schedules.create(hourly_schedule)
print("Hourly schedule created (ID: {}).".format(hourly_schedule.id))

# Daily Schedule
# This schedule will run every day at 5AM
daily_interval = TSC.DailyInterval(start_time=time(5))
daily_schedule = TSC.ScheduleItem("Daily-Schedule", 60, TSC.ScheduleItem.Type.Subscription,
TSC.ScheduleItem.ExecutionOrder.Serial, daily_interval)
daily_schedule = server.schedules.create(daily_schedule)
print("Daily schedule created (ID: {}).".format(daily_schedule.id))

# Weekly Schedule
# This schedule will wun every Monday, Wednesday, and Friday at 7:15PM
weekly_interval = TSC.WeeklyInterval(time(19, 15),
TSC.IntervalItem.Day.Monday,
TSC.IntervalItem.Day.Wednesday,
TSC.IntervalItem.Day.Friday)
weekly_schedule = TSC.ScheduleItem("Weekly-Schedule", 70, TSC.ScheduleItem.Type.Extract,
TSC.ScheduleItem.ExecutionOrder.Serial, weekly_interval)
weekly_schedule = server.schedules.create(weekly_schedule)
print("Weekly schedule created (ID: {}).".format(weekly_schedule.id))

# Monthly Schedule
# This schedule will run on the 15th of every month at 11:30PM
monthly_interval = TSC.MonthlyInterval(start_time=time(23, 30),
interval_value=15)
monthly_schedule = TSC.ScheduleItem("Monthly-Schedule", 80, TSC.ScheduleItem.Type.Subscription,
TSC.ScheduleItem.ExecutionOrder.Parallel, monthly_interval)
monthly_schedule = server.schedules.create(monthly_schedule)
print("Monthly schedule created (ID: {}).".format(monthly_schedule.id))


if __name__ == '__main__':
main()
94 changes: 51 additions & 43 deletions samples/explore_datasource.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
####
# This script demonstrates how to use the Tableau Server API
# This script demonstrates how to use the Tableau Server Client
# to interact with datasources. It explores the different
# functions that the Server API supports on datasources.
#
Expand All @@ -9,56 +9,64 @@
# on top of the general operations.
####


import tableauserverclient as TSC
import os.path
import argparse
import getpass
import logging

parser = argparse.ArgumentParser(description='Explore datasource functions supported by the Server API.')
parser.add_argument('--server', '-s', required=True, help='server address')
parser.add_argument('--username', '-u', required=True, help='username to sign into server')
parser.add_argument('--publish', '-p', metavar='FILEPATH', help='path to datasource to publish')
parser.add_argument('--download', '-d', metavar='FILEPATH', help='path to save downloaded datasource')
parser.add_argument('--logging-level', '-l', choices=['debug', 'info', 'error'], default='error',
help='desired logging level (set to error by default)')
args = parser.parse_args()
import tableauserverclient as TSC


def main():

parser = argparse.ArgumentParser(description='Explore datasource functions supported by the Server API.')
parser.add_argument('--server', '-s', required=True, help='server address')
parser.add_argument('--username', '-u', required=True, help='username to sign into server')
parser.add_argument('--publish', '-p', metavar='FILEPATH', help='path to datasource to publish')
parser.add_argument('--download', '-d', metavar='FILEPATH', help='path to save downloaded datasource')
parser.add_argument('--logging-level', '-l', choices=['debug', 'info', 'error'], default='error',
help='desired logging level (set to error by default)')

args = parser.parse_args()

password = getpass.getpass("Password: ")

# Set logging level based on user input, or error by default
logging_level = getattr(logging, args.logging_level.upper())
logging.basicConfig(level=logging_level)

password = getpass.getpass("Password: ")
# SIGN IN
tableau_auth = TSC.TableauAuth(args.username, password)
server = TSC.Server(args.server)
with server.auth.sign_in(tableau_auth):
# Query projects for use when demonstrating publishing and updating
all_projects, pagination_item = server.projects.get()
default_project = next((project for project in all_projects if project.is_default()), None)

# Set logging level based on user input, or error by default
logging_level = getattr(logging, args.logging_level.upper())
logging.basicConfig(level=logging_level)
# Publish datasource if publish flag is set (-publish, -p)
if args.publish:
if default_project is not None:
new_datasource = TSC.DatasourceItem(default_project.id)
new_datasource = server.datasources.publish(
new_datasource, args.publish, TSC.Server.PublishMode.Overwrite)
print("Datasource published. ID: {}".format(new_datasource.id))
else:
print("Publish failed. Could not find the default project.")

# SIGN IN
tableau_auth = TSC.TableauAuth(args.username, password)
server = TSC.Server(args.server)
with server.auth.sign_in(tableau_auth):
# Query projects for use when demonstrating publishing and updating
all_projects, pagination_item = server.projects.get()
default_project = next((project for project in all_projects if project.is_default()), None)
# Gets all datasource items
all_datasources, pagination_item = server.datasources.get()
print("\nThere are {} datasources on site: ".format(pagination_item.total_available))
print([datasource.name for datasource in all_datasources])

# Publish datasource if publish flag is set (-publish, -p)
if args.publish:
if default_project is not None:
new_datasource = TSC.DatasourceItem(default_project.id)
new_datasource = server.datasources.publish(new_datasource, args.publish, server.PublishMode.Overwrite)
print("Datasource published. ID: {}".format(new_datasource.id))
else:
print("Publish failed. Could not find the default project.")
if all_datasources:
# Pick one datasource from the list
sample_datasource = all_datasources[0]

# Gets all datasource items
all_datasources, pagination_item = server.datasources.get()
print("\nThere are {} datasources on site: ".format(pagination_item.total_available))
print([datasource.name for datasource in all_datasources])
# Populate connections
server.datasources.populate_connections(sample_datasource)
print("\nConnections for {}: ".format(sample_datasource.name))
print(["{0}({1})".format(connection.id, connection.datasource_name)
for connection in sample_datasource.connections])

if all_datasources:
# Pick one datasource from the list
sample_datasource = all_datasources[0]

# Populate connections
server.datasources.populate_connections(sample_datasource)
print("\nConnections for {}: ".format(sample_datasource.name))
print(["{0}({1})".format(connection.id, connection.datasource_name)
for connection in sample_datasource.connections])
if __name__ == '__main__':
main()
Loading