Skip to content

Commit

Permalink
Merge pull request #1549 from tableau/development
Browse files Browse the repository at this point in the history
v0.35
  • Loading branch information
jacalata authored Jan 4, 2025
2 parents 1d98fda + ec10c60 commit c5e016f
Show file tree
Hide file tree
Showing 43 changed files with 3,204 additions and 2,114 deletions.
13 changes: 11 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[build-system]
requires = ["setuptools>=68.0", "versioneer>=0.29", "wheel"]
requires = ["setuptools>=75.0", "versioneer[toml]==0.29", "wheel"]
build-backend = "setuptools.build_meta"

[project]
Expand All @@ -16,7 +16,7 @@ dependencies = [
'packaging>=23.1', # latest as at 7/31/23
'requests>=2.32', # latest as at 7/31/23
'urllib3>=2.2.2,<3',
'typing_extensions>=4.0.1',
'typing_extensions>=4.0',
]
requires-python = ">=3.9"
classifiers = [
Expand All @@ -38,6 +38,7 @@ test = ["black==24.8", "build", "mypy==1.4", "pytest>=7.0", "pytest-cov", "pytes
[tool.black]
line-length = 120
target-version = ['py39', 'py310', 'py311', 'py312', 'py313']
force-exclude = "tableauserverclient/bin/*"

[tool.mypy]
check_untyped_defs = false
Expand All @@ -50,7 +51,15 @@ show_error_codes = true
ignore_missing_imports = true # defusedxml library has no types
no_implicit_reexport = true
implicit_optional = true
exclude = ['/bin/']

[tool.pytest.ini_options]
testpaths = ["test"]
addopts = "--junitxml=./test.junit.xml"

[tool.versioneer]
VCS = "git"
style = "pep440-pre"
versionfile_source = "tableauserverclient/bin/_version.py"
versionfile_build = "tableauserverclient/bin/_version.py"
tag_prefix = "v"
19 changes: 12 additions & 7 deletions samples/create_extract_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ def main():
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
parser.add_argument("resource_type", choices=["workbook", "datasource"])
parser.add_argument("resource_id")
parser.add_argument("--incremental", default=False)

args = parser.parse_args()

Expand All @@ -45,6 +47,7 @@ def main():
# 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)
print(monthly_interval)
monthly_schedule = TSC.ScheduleItem(
None,
None,
Expand All @@ -53,18 +56,20 @@ def main():
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]
my_workbook: TSC.WorkbookItem = server.workbooks.get_by_id(args.resource_id)

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

extract_item = TSC.TaskItem(
refresh_type = "FullRefresh"
if args.incremental:
refresh_type = "Incremental"

scheduled_extract_item = TSC.TaskItem(
None,
"FullRefresh",
refresh_type,
None,
None,
None,
Expand All @@ -74,7 +79,7 @@ def main():
)

try:
response = server.tasks.create(extract_item)
response = server.tasks.create(scheduled_extract_item)
print(response)
except Exception as e:
print(e)
Expand Down
46 changes: 37 additions & 9 deletions samples/extracts.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@ def main():
help="desired logging level (set to error by default)",
)
# Options specific to this sample
parser.add_argument("--delete")
parser.add_argument("--create")
parser.add_argument("--create", action="store_true")
parser.add_argument("--delete", action="store_true")
parser.add_argument("--refresh", action="store_true")
parser.add_argument("--workbook", required=False)
parser.add_argument("--datasource", required=False)
args = parser.parse_args()

# Set logging level based on user input, or error by default
Expand All @@ -39,20 +42,45 @@ def main():
server.add_http_options({"verify": False})
server.use_server_version()
with server.auth.sign_in(tableau_auth):
# Gets all workbook items
all_workbooks, pagination_item = server.workbooks.get()
print(f"\nThere are {pagination_item.total_available} workbooks on site: ")
print([workbook.name for workbook in all_workbooks])

if all_workbooks:
# Pick one workbook from the list
wb = all_workbooks[3]
wb = None
ds = None
if args.workbook:
wb = server.workbooks.get_by_id(args.workbook)
if wb is None:
raise ValueError(f"Workbook not found for id {args.workbook}")
elif args.datasource:
ds = server.datasources.get_by_id(args.datasource)
if ds is None:
raise ValueError(f"Datasource not found for id {args.datasource}")
else:
# Gets all workbook items
all_workbooks, pagination_item = server.workbooks.get()
print(f"\nThere are {pagination_item.total_available} workbooks on site: ")
print([workbook.name for workbook in all_workbooks])

if all_workbooks:
# Pick one workbook from the list
wb = all_workbooks[3]

if args.create:
print("create extract on wb ", wb.name)
extract_job = server.workbooks.create_extract(wb, includeAll=True)
print(extract_job)

if args.refresh:
extract_job = None
if ds is not None:
print(f"refresh extract on datasource {ds.name}")
extract_job = server.datasources.refresh(ds, includeAll=True, incremental=True)
elif wb is not None:
print(f"refresh extract on workbook {wb.name}")
extract_job = server.workbooks.refresh(wb)
else:
print("no content item selected to refresh")

print(extract_job)

if args.delete:
print("delete extract on wb ", wb.name)
jj = server.workbooks.delete_extract(wb)
Expand Down
40 changes: 32 additions & 8 deletions samples/publish_workbook.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,16 @@ def main():
help="desired logging level (set to error by default)",
)
# Options specific to this sample
group = parser.add_mutually_exclusive_group(required=False)
group.add_argument("--thumbnails-user-id", "-u", help="User ID to use for thumbnails")
group.add_argument("--thumbnails-group-id", "-g", help="Group ID to use for thumbnails")

parser.add_argument("--workbook-name", "-n", help="Name with which to publish the workbook")
parser.add_argument("--file", "-f", help="local filepath of the workbook to publish")
parser.add_argument("--as-job", "-a", help="Publishing asynchronously", action="store_true")
parser.add_argument("--skip-connection-check", "-c", help="Skip live connection check", action="store_true")
parser.add_argument("--project", help="Project within which to publish the workbook")
parser.add_argument("--show-tabs", help="Publish workbooks with tabs displayed", action="store_true")

args = parser.parse_args()

Expand All @@ -48,11 +55,22 @@ def main():

# Step 1: Sign in to server.
tableau_auth = TSC.PersonalAccessTokenAuth(args.token_name, args.token_value, site_id=args.site)
server = TSC.Server(args.server, use_server_version=True)
server = TSC.Server(args.server, use_server_version=True, http_options={"verify": False})
with server.auth.sign_in(tableau_auth):
# Step 2: Get all the projects on server, then look for the default one.
all_projects, pagination_item = server.projects.get()
default_project = next((project for project in all_projects if project.is_default()), None)
# Step2: Retrieve the project id, if a project name was passed
if args.project is not None:
req_options = TSC.RequestOptions()
req_options.filter.add(
TSC.Filter(TSC.RequestOptions.Field.Name, TSC.RequestOptions.Operator.Equals, args.project)
)
projects = list(TSC.Pager(server.projects, req_options))
if len(projects) > 1:
raise ValueError("The project name is not unique")
project_id = projects[0].id
else:
# Get all the projects on server, then look for the default one.
all_projects, pagination_item = server.projects.get()
project_id = next((project for project in all_projects if project.is_default()), None).id

connection1 = ConnectionItem()
connection1.server_address = "mssql.test.com"
Expand All @@ -67,10 +85,16 @@ def main():
all_connections.append(connection1)
all_connections.append(connection2)

# Step 3: If default project is found, form a new workbook item and publish.
# Step 3: Form a new workbook item and publish.
overwrite_true = TSC.Server.PublishMode.Overwrite
if default_project is not None:
new_workbook = TSC.WorkbookItem(default_project.id)
if project_id is not None:
new_workbook = TSC.WorkbookItem(
project_id=project_id,
name=args.workbook_name,
show_tabs=args.show_tabs,
thumbnails_user_id=args.thumbnails_user_id,
thumbnails_group_id=args.thumbnails_group_id,
)
if args.as_job:
new_job = server.workbooks.publish(
new_workbook,
Expand All @@ -92,7 +116,7 @@ def main():
)
print(f"Workbook published. ID: {new_workbook.id}")
else:
error = "The default project could not be found."
error = "The destination project could not be found."
raise LookupError(error)


Expand Down
33 changes: 25 additions & 8 deletions samples/refresh.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,34 +27,51 @@ def main():
# Options specific to this sample
parser.add_argument("resource_type", choices=["workbook", "datasource"])
parser.add_argument("resource_id")
parser.add_argument("--incremental")
parser.add_argument("--synchronous")

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)

refresh_type = "FullRefresh"
incremental = False
if args.incremental:
refresh_type = "Incremental"
incremental = True

tableau_auth = TSC.PersonalAccessTokenAuth(args.token_name, args.token_value, site_id=args.site)
server = TSC.Server(args.server, use_server_version=True)
server = TSC.Server(args.server, use_server_version=True, http_options={"verify": False})
with server.auth.sign_in(tableau_auth):
if args.resource_type == "workbook":
# Get the workbook by its Id to make sure it exists
resource = server.workbooks.get_by_id(args.resource_id)
print(resource)

# trigger the refresh, you'll get a job id back which can be used to poll for when the refresh is done
job = server.workbooks.refresh(args.resource_id)
job = server.workbooks.refresh(args.resource_id, incremental=incremental)
else:
# Get the datasource by its Id to make sure it exists
resource = server.datasources.get_by_id(args.resource_id)
print(resource)

# server.datasources.create_extract(resource)

# trigger the refresh, you'll get a job id back which can be used to poll for when the refresh is done
job = server.datasources.refresh(resource)
job = server.datasources.refresh(resource, incremental=incremental) # by default runs as a sync task,

print(f"Update job posted (ID: {job.id})")
print("Waiting for job...")
# `wait_for_job` will throw if the job isn't executed successfully
job = server.jobs.wait_for_job(job)
print("Job finished succesfully")
print(f"{refresh_type} job posted (ID: {job.id})")
if args.synchronous:
# equivalent to tabcmd --synchnronous: wait for the job to complete
try:
# `wait_for_job` will throw if the job isn't executed successfully
print("Waiting for job...")
server.jobs.wait_for_job(job)
print("Job finished succesfully")
except Exception as e:
print(f"Job failed! {e}")


if __name__ == "__main__":
Expand Down
10 changes: 0 additions & 10 deletions setup.cfg

This file was deleted.

9 changes: 0 additions & 9 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,6 @@
import versioneer
from setuptools import setup

"""
once versioneer 0.25 gets released, we can move this from setup.cfg to pyproject.toml
[tool.versioneer]
VCS = "git"
style = "pep440-pre"
versionfile_source = "tableauserverclient/_version.py"
versionfile_build = "tableauserverclient/_version.py"
tag_prefix = "v"
"""
setup(
version=versioneer.get_version(),
cmdclass=versioneer.get_cmdclass(),
Expand Down
6 changes: 5 additions & 1 deletion tableauserverclient/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from tableauserverclient._version import get_versions
from tableauserverclient.bin._version import get_versions
from tableauserverclient.namespace import NEW_NAMESPACE as DEFAULT_NAMESPACE
from tableauserverclient.models import (
BackgroundJobItem,
Expand Down Expand Up @@ -133,3 +133,7 @@
"WeeklyInterval",
"WorkbookItem",
]

from .bin import _version

__version__ = _version.get_versions()["version"]
Loading

0 comments on commit c5e016f

Please sign in to comment.