如何将 poll/wait 添加到 python 脚本中以刷新画面工作簿提取?

How to add poll/wait into python script for refreshing a tableau workbook extract?

我已经编写了一个 python 脚本来调用 Tableau Rest API,我让它正常工作。它提示用户输入他们的登录凭据、select 服务器、select 站点、select 工作簿,然后找到所有必要的密钥并提交基于工作簿的提取刷新请求ID。 server.workbooks.refresh 方法在 Tableau Server 上启动数据提取刷新作业,我从方法 return 中获取了作业 ID。

我接下来要做的是在脚本中构建一个进程,以使用该 jobID 轮询 Tableau Server 以查找完成时间和状态,然后 post 一条消息表明刷新已完成并关闭脚本。

我在 python 中查找了一些有关如何执行 polling/waiting 的 youtube 视频,但我不确定如何使用 tableau 服务器应用这些方法。我希望有人有一段代码来执行与画面服务器进程相关的轮询?

with server.auth.sign_in(tableau_auth):
    get_sites(server)
    print(selected_site_id)

    #tab_site = selected_site_id

    # Get all projects on site
    get_projects(server)

    if input_resource_type.lower() == 'workbook':
        # Get a list of workbooks
        get_workbooks(server)

    results = server.workbooks.refresh(selected_workbook_id)

    print("refresh results: " + str(results))

我希望 python 脚本保持 运行 直到与 Tableau Server 上的 JobID 关联的任务完成并具有成功状态代码。

目前,代码只是在服务器中启动刷新提取任务,returnJobID。

轮询时您的程序需要做什么吗?如果不是,则将您的轮询代码置于循环中并使用睡眠,这样您就不会过于频繁地访问服务器。当确定任务完成后,退出循环。

这是进行轮询的通用方法,可以与 Tableau 或其他任何工具一起使用。不是最有效的,但它很简单并且有效。

只是为了跟进如何为其他尝试这样做的人解决这个问题。正如 jdigital 所说,这非常有效......我在代码中添加了一些注释,以便在进程为 运行:

时通知用户
        jobid = results.id

        complete_time = None
        counter = 0
        started = False
        sleep_timer = 5
        while complete_time is None:
            extract = server.jobs.get_by_id(jobid)

            if str(extract.finish_code) == "0":
                complete_time = str(extract.completed_at)
            else:
                if extract.started_at is None:
                    print("refresh has not started")
                else:
                    if started == False:
                        print("refresh started at " + str(extract.started_at))
                        started = True

                    if counter == 0:
                        print("refresh is running....")
                    else:
                        print("refresh is still running.....")

                    counter += 1

            if complete_time is None:
                time.sleep(sleep_timer)

        refresh_time = counter * sleep_timer
        print("############################################")
        print(" Refreshed the " + str(workbook.name) + " workbook \n")
        print(" Extract refresh started at " + str(extract.started_at) + "\n")
        print(" Extract refresh completed at " + str(complete_time) + "\n")
        print(" Extract took approximately " + str(refresh_time) + " seconds to refresh")
        print("############################################")

我用这个函数来保持最大作业数运行

def wait_jobs_in_progress_to_finish(tableau_auth, max_jobs_in_progress=3, wait_seconds=10):
    req = TSC.RequestOptions()
    req.filter.add(TSC.Filter("progress", TSC.RequestOptions.Operator.LessThanOrEqual, 0))
    if len(list(TSC.Pager(server.jobs, request_opts=req))) >= max_jobs_in_progress:
        sleep(wait_seconds)
        wait_jobs_in_progress_to_finish(tableau_auth, max_jobs_in_progress=max_jobs_in_progress, wait_seconds=wait_seconds)
    else: return None

也许您会发现 运行 计划中的工作的整个代码片段很有用:

with server.auth.sign_in(tableau_auth):
    # Select Schedule
    all_schedules, pagination_item = server.schedules.get()
    for schedule in all_schedules:
        if schedule.name == 'Daily Morning':
            schedule_id = schedule.id
            print(schedule_id)

    # Run all Tasks from this Schedule  
    tasks, pagination = server.tasks.get()
    tasks = [task for task in tasks if task.schedule_id == schedule_id]
    # Sort by priority
    tasks.sort(key = lambda t: t.priority)
    for task in tasks:
        print("{}".format(task))
        server.tasks.run(task)
        wait_jobs_in_progress_to_finish(max_jobs_in_progress=3, wait_seconds=10)