Skip to main content
Richard Gazzo a posé une question dans #Tableau APIs & Embedding

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)

2 réponses
  1. 9 nov. 2022, 23:47

    @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)"

    @Richard Gazzo​ Hi, I have been working a little in a code that may work for you:from tableaudocumentapi import Datasourcefrom tableaudocumentapi import Workbookfrom tableaudocumentapi import Connecti 

     

    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

0/9000