Skip to content
Merged

0.27 #1272

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
fc9568d
Update user_item.py (#1217)
ma7tcsp Apr 12, 2023
3cc28be
run long requests on second thread (#1212)
jacalata Apr 19, 2023
830a3a6
Jac/small things (#1215)
jacalata Apr 13, 2023
a29d6eb
update datasource to use bridge (#1224)
jacalata Apr 24, 2023
4e55d99
Merge branch 'master' into development
jacalata Apr 24, 2023
beda2d8
fix imports
jacalata Apr 24, 2023
5650adc
846 fix filter in operator spaces bug (#1259)
LarsBreddemann Jul 25, 2023
66064c5
fix: remove logging configuration from TSC (#1248)
jorwoods Jul 31, 2023
f56b2c7
feat: add JWTAuth (#1219)
jorwoods Aug 1, 2023
77f2f63
Jac/schedules (#1266)
jacalata Aug 1, 2023
574118a
add powerpoint example in samples (#1262)
jacalata Aug 1, 2023
4caf0a5
pin black and mypy versions, update many dependencies (#1265)
jacalata Aug 1, 2023
2821592
Add publish samples attribute (#1264)
jacalata Aug 1, 2023
90cf332
Update actions to newer versions to get supported Node versions (#1267)
bcantoni Aug 1, 2023
15086b8
Added 'getting started' samples (#1263)
jacalata Aug 1, 2023
439a333
Merge branch 'master' into development
jacalata Aug 16, 2023
01e0372
Fix newline for clean Black run
bcantoni Aug 17, 2023
5a5772c
add support for custom schedules in TOL (#1273)
a-torres-2 Aug 29, 2023
9afc0b3
Added Filtering Capability for Tableau Download View Crosstab Excel (…
wlodi83 Sep 21, 2023
81af54a
Enable asJob for group update (#1276)
jorwoods Sep 21, 2023
3a49700
Fix shared attribute for custom views (#1280)
jorwoods Sep 22, 2023
f94f72d
run long requests on second thread (#1212)
jacalata Apr 19, 2023
c812e4b
fix imports
jacalata Apr 24, 2023
9f2e870
Sep 21, 2023, 9:36 PM
jacalata Sep 22, 2023
c1e17ce
Sep 21, 2023, 10:42 PM
jacalata Sep 22, 2023
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
4 changes: 2 additions & 2 deletions .github/workflows/code-coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ jobs:
runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3

- name: Set up Python ${{ matrix.python-version }} on ${{ matrix.os }}
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/meta-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ jobs:
runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3

- name: Set up Python ${{ matrix.python-version }} on ${{ matrix.os }}
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish-pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: actions/setup-python@v1
- uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Build dist files
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ['3.7', '3.8', '3.9', '3.10']
python-version: ['3.8', '3.9', '3.10', '3.11']

runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3

- name: Set up Python ${{ matrix.python-version }} on ${{ matrix.os }}
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

Expand All @@ -33,4 +33,4 @@ jobs:
- name: Test build
if: always()
run: |
python -m build
python -m build
26 changes: 14 additions & 12 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[build-system]
requires = ["setuptools>=45.0", "versioneer>=0.24", "wheel"]
requires = ["setuptools>=68.0", "versioneer>=0.29", "wheel"]
build-backend = "setuptools.build_meta"

[project]
Expand All @@ -12,39 +12,41 @@ license = {file = "LICENSE"}
readme = "README.md"

dependencies = [
'defusedxml>=0.7.1',
'packaging>=22.0', # bumping to minimum version required by black
'requests>=2.28',
'urllib3~=1.26.8',
'defusedxml>=0.7.1', # latest as at 7/31/23
'packaging>=23.1', # latest as at 7/31/23
'requests>=2.31', # latest as at 7/31/23
'urllib3==2.0.4', # latest as at 7/31/23
]
requires-python = ">=3.7"
classifiers = [
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10"
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12"
]
[project.urls]
repository = "https://github.com/tableau/server-client-python"

[project.optional-dependencies]
test = ["argparse", "black", "mock", "mypy", "pytest>=7.0", "pytest-subtests", "requests-mock>=1.0,<2.0"]
test = ["argparse", "black==23.7", "mock", "mypy==1.4", "pytest>=7.0", "pytest-subtests", "requests-mock>=1.0,<2.0"]

[tool.black]
line-length = 120
target-version = ['py37', 'py38', 'py39', 'py310']
target-version = ['py37', 'py38', 'py39', 'py310', 'py311', 'py312']

[tool.mypy]
check_untyped_defs = false
disable_error_code = [
'misc',
'import'
# tableauserverclient\server\endpoint\datasources_endpoint.py:48: error: Cannot assign multiple types to name "FilePath" without an explicit "Type[...]" annotation [misc]
'annotation-unchecked' # can be removed when check_untyped_defs = true
]
files = ["tableauserverclient", "test"]
show_error_codes = true
ignore_missing_imports = true

ignore_missing_imports = true # defusedxml library has no types
[tool.pytest.ini_options]
testpaths = ["test"]
addopts = "--junitxml=./test.junit.xml"
84 changes: 84 additions & 0 deletions samples/create_extract_task.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
####
# This script demonstrates how to create extract tasks in Tableau Cloud
# using the Tableau Server Client.
#
# To run the script, you must have installed Python 3.7 or later.
####


import argparse
import logging

from datetime import time

import tableauserverclient as TSC


def main():
parser = argparse.ArgumentParser(description="Creates sample extract refresh task.")
# Common options; please keep those in sync across all samples
parser.add_argument("--server", "-s", help="server address")
parser.add_argument("--site", "-S", help="site name")
parser.add_argument("--token-name", "-p", help="name of the personal access token used to sign into the server")
parser.add_argument("--token-value", "-v", help="value of the personal access token used to sign into the server")
parser.add_argument(
"--logging-level",
"-l",
choices=["debug", "info", "error"],
default="error",
help="desired logging level (set to error by default)",
)
# Options specific to this sample:
# This sample has no additional options, yet. If you add some, please add them here

args = parser.parse_args()

# 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.PersonalAccessTokenAuth(args.token_name, args.token_value, site_id=args.site)
server = TSC.Server(args.server, use_server_version=False)
server.add_http_options({"verify": False})
server.use_server_version()
with server.auth.sign_in(tableau_auth):
# 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(
None,
None,
None,
None,
monthly_interval,
)

# Default to using first workbook found in server
all_workbook_items, pagination_item = server.workbooks.get()
my_workbook: TSC.WorkbookItem = all_workbook_items[0]

target_item = TSC.Target(
my_workbook.id, # the id of the workbook or datasource
"workbook", # alternatively can be "datasource"
)

extract_item = TSC.TaskItem(
None,
"FullRefresh",
None,
None,
None,
monthly_schedule,
None,
target_item,
)

try:
response = server.tasks.create(extract_item)
print(response)
except Exception as e:
print(e)


if __name__ == "__main__":
main()
9 changes: 8 additions & 1 deletion samples/create_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,14 @@ def main():
server.use_server_version()

# Without parent_id specified, projects are created at the top level.
top_level_project = TSC.ProjectItem(name="Top Level Project")
# With the publish-samples attribute, the project will be created with sample items
top_level_project = TSC.ProjectItem(
name="Top Level Project",
description="A sample tsc project",
content_permissions=None,
parent_id=None,
samples=True,
)
top_level_project = create_project(server, top_level_project)

# Specifying parent_id creates a nested projects.
Expand Down
10 changes: 10 additions & 0 deletions samples/explore_workbook.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ def main():
parser.add_argument(
"--preview-image", "-i", metavar="FILENAME", help="filename (a .png file) to save the preview image"
)
parser.add_argument(
"--powerpoint", "-ppt", metavar="FILENAME", help="filename (a .ppt file) to save the powerpoint deck"
)

args = parser.parse_args()

Expand Down Expand Up @@ -145,6 +148,13 @@ def main():
f.write(c.image)
print("saved to " + filename)

if args.powerpoint:
# Populate workbook preview image
server.workbooks.populate_powerpoint(sample_workbook)
with open(args.powerpoint, "wb") as f:
f.write(sample_workbook.powerpoint)
print("\nDownloaded powerpoint of workbook to {}".format(os.path.abspath(args.powerpoint)))

if args.delete:
print("deleting {}".format(c.id))
unlucky = TSC.CustomViewItem(c.id)
Expand Down
21 changes: 21 additions & 0 deletions samples/getting_started/1_hello_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
####
# Getting started Part One of Three
# This script demonstrates how to use the Tableau Server Client to connect to a server
# You don't need to have a site or any experience with Tableau to run it
#
####

import tableauserverclient as TSC


def main():
# This is the domain for Tableau's Developer Program
server_url = "https://10ax.online.tableau.com"
server = TSC.Server(server_url)
print("Connected to {}".format(server.server_info.baseurl))
print("Server information: {}".format(server.server_info))
print("Sign up for a test site at https://www.tableau.com/developer")


if __name__ == "__main__":
main()
50 changes: 50 additions & 0 deletions samples/getting_started/2_hello_site.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
####
# Getting started Part Two of Three
# This script demonstrates how to use the Tableau Server Client to
# view the content on an existing site on Tableau Server/Online
# It assumes that you have already got a site and can visit it in a browser
#
####

import getpass
import tableauserverclient as TSC


# 0 - launch your Tableau site in a web browser and look at the url to set the values below
def main():
# 1 - replace with your server domain: stop at the slash
server_url = "https://10ax.online.tableau.com"

# 2 - optional - change to false **for testing only** if you get a certificate error
use_ssl = True

server = TSC.Server(server_url, use_server_version=True, http_options={"verify": use_ssl})
print("Connected to {}".format(server.server_info.baseurl))

# 3 - replace with your site name exactly as it looks in the url
# e.g https://my-server/#/site/this-is-your-site-url-name/not-this-part
site_url_name = "" # leave empty if there is no site name in the url (you are on the default site)

# 4 - replace with your username.
# REMEMBER: if you are using Tableau Online, your username is the entire email address
username = "your-username-here"
password = getpass.getpass("Your password:") # so you don't save it in this file
tableau_auth = TSC.TableauAuth(username, password, site_id=site_url_name)

# OR instead of username+password, uncomment this section to use a Personal Access Token
# token_name = "your-token-name"
# token_value = "your-token-value-long-random-string"
# tableau_auth = TSC.PersonalAccessTokenAuth(token_name, token_value, site_id=site_url_name)

with server.auth.sign_in(tableau_auth):
projects, pagination = server.projects.get()
if projects:
print("{} projects".format(pagination.total_available))
project = projects[0]
print(project.name)

print("Done")


if __name__ == "__main__":
main()
Loading