I am writing a script to download a workbook using TSC, modify it using the document API, and then Republish it using TSC. This all works fine, but is re-publishing to the "Default" folder as I am having trouble getting the projectID from the workbook name to pass into the publish step:
# Step 3: Download workbook to a temp directory
if len(all_workbooks) == 0:
print("No workbook named {} found.".format(args.workbook_name))
else:
#Start of line to get project id from workbook name, not working
get_projName = source_server.workbooks.get(all_workbooks[0].project_id)
#End of line not working
source_server.workbooks.download(all_workbooks[0].id)
#Step4: Use document API to update data connections
curr_wb.datasources[0].connections[0].server = "servername"
curr_wb.datasources[0].connections[0].dbname = "dbname"
curr_wb.datasources[0].connections[0].username = "username"
curr_wb.save()
#Step5: Publish updated workbook
#would like to pass project id into project_id
curr_wb = TSC.WorkbookItem(name=args.workbook_name, project_id="")
curr_wb = source_server.workbooks.publish(curr_wb, path, mode=TSC.Server.PublishMode.Overwrite, skip_connection_check = True)
@Richard Gazzo
Hi, I have been working a little in a code that may work for you:
from tableaudocumentapi import Datasource
from tableaudocumentapi import Workbook
from tableaudocumentapi import Connection
from sys import exit
import tableauserverclient as TSC
import pathlib
import os
# source information
SOURCE_SERVER_NAME = "https://www.yourserver.com"
SOURCE_SERVER_USERNAME = "youruser"
SOURCE_SERVER_PASSWORD = "yourpassword"
SOURCE_SITE_NAME = ''
SOURCE_WORKBOOK_NAME = "RestApi"
SOURCE_DATA_SOURCE_NAME = "Ventas (Superstore_dev)"
# changing data source
TARGET_DATA_SOURCE_NAME = None
#If TARGET_DATA_SOURCE_NAME is None, the name would be the same as the SOURCE_DATA_SOURCE_NAME
#TARGET_DATA_SOURCE_NAME = "Ventas (Superstore_prod)"
TARGET_DATA_SOURCE_DATABASE = "Superstore_prod"
TARGET_DATA_SOURCE_SERVER = "yourdatabasehost"
TARGET_DATA_SOURCE_USER = "yourdatabaseuser"
TARGET_DATA_SOURCE_PASSWORD = "yourdatabasepassword"
# target server
TARGET_SERVER_NAME = "https://www.yourdestinationserver.com"
TARGET_SERVER_USERNAME = "yourdestinationuser"
TARGET_SERVER_PASSWORD = "yourdestinationpassword"
TARGET_SITE_NAME = None
#If TARGET_SITE_NAME is None, then the name will be the same as SOURCE_SITE_NAME
#TARGET_SITE_NAME = ''
TARGET_PROJECT_NAME = None
#If TARGET_PROJECT_NAME is None, then the name will be inherited from workbook project.
#TARGET_PROJECT_NAME = 'Default'
TARGET_WORKBOOK_NAME = None
#If TARGET_WORKBOOK_NAME is None, then the name will be inherited from workbook name.
#TARGET_WORKBOOK_NAME = "RestApi"
source_server = TSC.Server(SOURCE_SERVER_NAME, use_server_version=True)
source_tableau_auth = TSC.TableauAuth(SOURCE_SERVER_USERNAME, SOURCE_SERVER_PASSWORD, \
SOURCE_SITE_NAME)
with source_server.auth.sign_in(source_tableau_auth):
print('Logged in to source server successfully')
req_option = TSC.RequestOptions()
req_option.filter.add(TSC.Filter(TSC.RequestOptions.Field.Name,
TSC.RequestOptions.Operator.Equals, SOURCE_WORKBOOK_NAME))
all_workbooks, pagination_item = source_server.workbooks.get(req_option)
⌗Download workbook to a temp directory
if len(all_workbooks) == 0:
print('No workbook named {} found.'.format(SOURCE_WORKBOOK_NAME))
exit()
elif len(all_workbooks) >= 2:
print('Several workbooks named {} found.'.format(SOURCE_WORKBOOK_NAME))
exit()
elif len(all_workbooks) == 1:
tmpdir = "resources"
isExist = os.path.exists(tmpdir)
if not isExist:
# Create a new directory because it does not exist
os.makedirs(tmpdir)
print("The new directory is created!")
try:
workbook_path = source_server.workbooks.download(all_workbooks[0].id, tmpdir)
print("workbook_path: '%s' " % (workbook_path,))
finally:
print("")
if TARGET_PROJECT_NAME is None:
TARGET_PROJECT_NAME = all_workbooks[0].project_name
if TARGET_WORKBOOK_NAME is None:
TARGET_WORKBOOK_NAME = all_workbooks[0].name
if TARGET_SITE_NAME is None:
TARGET_SITE_NAME = SOURCE_SITE_NAME
if TARGET_DATA_SOURCE_NAME is None:
TARGET_DATA_SOURCE_NAME = SOURCE_DATA_SOURCE_NAME
sourceWorkbook = Workbook(workbook_path)
sourceDataSource = None
sourceConnection = None
for tempDataSource in sourceWorkbook.datasources:
print("name ", tempDataSource.name)
print("caption ", tempDataSource.caption)
if tempDataSource.caption == SOURCE_DATA_SOURCE_NAME:
sourceConnection = tempDataSource.connections[0]
dataSource = tempDataSource
break
if sourceConnection is not None:
sourceConnection.server = TARGET_DATA_SOURCE_SERVER
sourceConnection.dbname = TARGET_DATA_SOURCE_DATABASE
sourceConnection.username = TARGET_DATA_SOURCE_USER
dataSource.caption = TARGET_DATA_SOURCE_NAME
⌗save updated workbook
extension = pathlib.Path(sourceWorkbook.filename).suffix
print("extension",extension)
sourceWorkbook.save_as("resources/updated" + extension)
else:
print("No Connection with name",SOURCE_DATA_SOURCE_NAME)
exit()
# publish modified workbook and update credentials
target_server = TSC.Server(TARGET_SERVER_NAME, use_server_version=True)
target_tableau_auth = TSC.TableauAuth(TARGET_SERVER_USERNAME, TARGET_SERVER_PASSWORD, \
TARGET_SITE_NAME)
with target_server.auth.sign_in(target_tableau_auth):
print('Logged in to target server successfully')
req_option = TSC.RequestOptions()
req_option.filter.add(TSC.Filter(TSC.RequestOptions.Field.Name,
TSC.RequestOptions.Operator.Equals, TARGET_PROJECT_NAME))
# If destination project is specific this could work, project name must be unique
dest_projects, pagination_info = target_server.projects.get(req_option)
if len(dest_projects) == 0:
print('No project named {} found.'.format(SOURCE_WORKBOOK_NAME))
exit()
elif len(dest_projects) >= 2:
print('Several projects named {} found.'.format(SOURCE_WORKBOOK_NAME))
exit()
elif len(dest_projects) == 1:
try:
target_project = dest_projects[0]
finally:
print("")
if target_project is not None:
new_connection_creds = TSC.ConnectionCredentials(name=TARGET_DATA_SOURCE_USER, password=TARGET_DATA_SOURCE_PASSWORD, embed=True, oauth=False)
new_workbook = TSC.WorkbookItem(name=TARGET_WORKBOOK_NAME, project_id=target_project.id)
new_workbook = target_server.workbooks.publish(new_workbook, "resources/updated" + extension, mode=TSC.Server.PublishMode.Overwrite, connection_credentials=new_connection_creds)
print("Successfully copied {0} ({1})".format(new_workbook.name, new_workbook.id))
else:
error = "The destination project could not be found."
raise LookupError(error)
Hope this works for you
SOURCE_DATA_SOURCE_NAME = "Ventas (Superstore_dev)"
If this post resolves the question, would you be so kind to "Select as Best"?. This will help other users find the same answer/resolution and help community keep track of answered questions. Thank you.
Regards,
Diego Martinez
Tableau Visionary and Forums Ambassador