Skip to main content

#Print0 utenti parlano di questo argomento

So far I have the list of users, but i don't know how to export them. Can anyone help me here?

 

import tableauserverclient as TSC

tableau_auth = TSC.PersonalAccessTokenAuth('TOKEN_NAME', 'TOKEN_VALUE', 'SITENAME')

server = TSC.Server('https://SERVER_URL', use_server_version=True)

 

with server.auth.sign_in(tableau_auth):

    # get specified the group

    req_option = TSC.RequestOptions()

    req_option.filter.add(TSC.Filter(TSC.RequestOptions.Field.Name,

                                 TSC.RequestOptions.Operator.Equals,

                                 'ABC'))

   

    all_groups, pagination_item = server.groups.get(req_option)

    mygroup = all_groups[0]

   

    print(mygroup.name,mygroup.id)

    #print(mygroup[0])

    # get user information from the group

    pagination_item = server.groups.populate_users(mygroup)

    # print the names of the users

    for user in mygroup.users:

        if user.last_login is None:

            print(user.name,user.site_role, user.last_login)

4 risposte
  1. 27 gen 2022, 13:08

    @Bhavana Khairnar​ 

    Hi, in this case you can use:

    import tableauserverclient as TSC

    import csv

     

    tableau_auth = TSC.PersonalAccessTokenAuth('TOKEN_NAME', 'TOKEN_VALUE', 'SITENAME')

    server = TSC.Server('https://SERVER_URL', use_server_version=True)

     

    #Create the csv file and open it in write mode

    f = open('usuarios.csv', 'w', encoding='UTF8', newline='')

     

    #delimiter with semicolon if needed change to comma

    writer = csv.writer(f, delimiter=";")

     

    #write the header

    header = ['User','Site Role','Last Login']

    writer.writerow(header)

     

    #tableau_auth = TSC.PersonalAccessTokenAuth('TOKEN_NAME', 'TOKEN_VALUE', 'SITENAME')

    #server = TSC.Server('https://SERVER_URL', use_server_version=True)

    with server.auth.sign_in(tableau_auth):

    # get specified the group

    req_option = TSC.RequestOptions()

    req_option.filter.add(TSC.Filter(TSC.RequestOptions.Field.Name,

    TSC.RequestOptions.Operator.Equals,

    'Modux'))

    all_groups, pagination_item = server.groups.get(req_option)

    mygroup = all_groups[0]

    print(mygroup.name,mygroup.id)

    #print(mygroup[0])

    # get user information from the group

    pagination_item = server.groups.populate_users(mygroup)

    # print the names of the users

    for user in mygroup.users:

    # if user.last_login is None:

    row=[user.name,user.site_role,user.last_login]

    print(user.name, user.site_role, user.last_login)

    #write the row

    writer.writerow(row)

    #Close file connection

    f.close()

    #Don't forget to sign out

    server.auth.sign_out()

     

    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

    Tableau Ambassador

0/9000
Hafiz Naim Bin Sahidi ha fatto una domanda in #Tableau Server

Sometimes, i received error that flow id 35 does not exist, eventho i'm confidence the flow exist inside the server. Can anyone help with this? Below are the code with the error.

 

For your information, i want to avoid creating .bat file and using task scheduler. I want to use python nowError running tableau flow using python and REST API. For your information, my account is Server Administrator. I keep on getting this error eventho i already have access for REST API and confirm that i already enabled REST API in my serverCode run flowError Tableau Flow

1 risposta
  1. 14 apr 2023, 11:23

    @Hafiz Naim Bin Sahidi​ 

    Hi, use the following code to run flows on Tableau Server:

    ####

    # This script demonstrates how to use the Tableau Server Client

    # to run the flow

    #

    # For signing into server, this script uses personal access tokens. For

    # more information on personal access tokens, refer to the documentations:

    # (https://help.tableau.com/current/server/en-us/security_personal_access_tokens.htm)

    #

    # If you don't know the flow name, the script list the flows name. If you need the list

    # of flows, just enter any name in the flow parameter

    #

    # To run the script, you must have installed Python 3.5 or later.

    ####

    import argparse

    import logging

    import tableauserverclient as TSC

    def main():

    parser = argparse.ArgumentParser(description='Publish a datasource to server.')

    parser.add_argument('--server', '-s', required=True, help='server address')

    parser.add_argument('--site', '-i', help='site name')

    parser.add_argument('--token-name', '-p', required=True,

    help='name of the personal access token used to sign into the server')

    parser.add_argument('--token-value', '-v', required=True,

    help='value of the personal access token used to sign into the server')

    parser.add_argument('--flow-name', '-f', required=True,

    help='The name of the flow')

    args = parser.parse_args()

    # 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)

    with server.auth.sign_in(tableau_auth):

    all_flow_items, pagination_item = server.flows.get()

    print("There are {} flows on site:" .format(pagination_item.total_available))

    print([[flow.id, flow.name] for flow in all_flow_items])

    for flow in all_flow_items:

    if flow.name == args.flow_name:

    print('Run Flow', flow.name, 'Now')

    # run the flow and get the JobItem

    job = server.flows.refresh(flow)

    print("Thanks for using this python script by www.modux.co")

    if __name__ == '__main__':

    main()

    We can modify this flow to not use args:

    ####

    # This script demonstrates how to use the Tableau Server Client

    # to run the flow

    #

    # For signing into server, this script could use personal access tokens. For

    # more information on personal access tokens, refer to the documentations:

    # (https://help.tableau.com/current/server/en-us/security_personal_access_tokens.htm)

    #

    # If you don't know the flow name, the script list the flows name. If you need the list

    # of flows, just enter any name in the flow parameter

    #

    # To run the script, you must have installed Python 3.5 or later.

    ####

     

    import tableauserverclient as TSC

     

     

    def main():

    SERVER = "www.yourserver.com"

    #Use "" for default site

    SITE = ""

    USER = "youruser"

    PWD = "yourpassword"

    FLOW_NAME = "Your Flow Name"

    #Use the following for PAT Sign in

    #TOKEN_NAME = ""

    #TOKEN_VALUE = ""

     

    # Sign in to server with PAT

    #tableau_auth = TSC.PersonalAccessTokenAuth(TOKEN_NAME, TOKEN_VALUE, site_id=SITE)

    # Sign in to server with USER/PWD

    tableau_auth = TSC.TableauAuth(USER, PWD)

    server = TSC.Server(SERVER, use_server_version=True)

    with server.auth.sign_in(tableau_auth):

    all_flow_items, pagination_item = server.flows.get()

    #print("There are {} flows on site:" .format(pagination_item.total_available))

    #print([[flow.id, flow.name] for flow in all_flow_items])

    for flow in all_flow_items:

    if flow.name == FLOW_NAME:

    print('Run Flow', flow.name, 'Now')

    # run the flow and get the JobItem

    job = server.flows.refresh(flow)

    print("Thanks for using this python script by www.modux.co")

     

    if __name__ == '__main__':

    main()

    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

Hi Everybody,

 

I am super new in API Section, I am writing api using python. I installed Postman and I just want to try simple sign in. So by following this article https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm⌗sign_in

 

I simply put this /api/api-version/auth/signin version in my postman with post request like this https://tableauServer/api/3.3/auth/signin    where 3.3 because I am using Tableau Server version 2019.1.2 and with my username and password of tableau Server and when I run it I get error bad request

 

Rest API Bad Request error

 

What is it I'm missing? Can anybody please help...In Postman itself i'm giving username and password is it enough? or should i add it in url only? 

Like this https://tableauServer/api/3.3/auth/signin?username='name'&password='pass'&content-url='text/xml'

 

and I have installed python 3.7v but I wrote a simple program in it and it was giving me SSL error, so my colleague suggested me to install postman and just check if I can at least connect to tableau server through postman so i tried and it doesn't give me any error.  but when i run this signin thing it gives me this error, now what to do? I think I am heading in wrong direction with very little help, any suggestions/solutions will be very helpful.

 

Thanks,

Bhavana

5 risposte
  1. 7 mag 2019, 13:26

    Hi Bhavana,

     

    You only want to use Postman for testing; it is not a tool for production work. I have used the REST api natively, but if you can use the TSC Python library you definitely should!

     

    Using the Python library is quite simple.

    If you want to remove all unlicensed users this should work:

     

    import tableauserverclient as TSC

    tableau_auth = TSC.TableauAuth('USER', 'PASSWORD')

    server = TSC.Server('SERVER')

     

    with server.auth.sign_in(tableau_auth):

      all_users, pagination_item = server.users.get()

       for user in all_users:

            print(user.name)

            print(user.site_role)

            if (user.site_role == 'Unlicensed'):

                 print(user.id)

                 server.users.remove(user.id)

                 print("user deleted") 

     

    This is dangerous - so make sure to test it and make backups!

     

    Kind regards

    Johan de Groot

0/9000

I have written some automations for my datasources instead of scheduling at some fixed time. But some of the data sources are of Live type and throw error when I try to refresh.

 

I am using Tableau Rest APIs to find all information about datasource but couldn't find any information wrt Live vs extract. Is there a way using Tableau APIs to find out this?

 

Thanks

14 risposte
0/9000

Hi,

 

How do you retrieve workbook id?

 

I am logged into the tableau server. I was wondering what is an easy way to get that id.

 

Thanks,

 

MD

7 risposte
0/9000

Hello All,

This is my first question here.

I have a python script which is giving me the required output. However the moment I run it in tableau (using SCRIPT_REAL) it says TypeError : Object of type DataFrame is not JSON serializable. the script is attached below:

 

SCRIPT_REAL("

import quants_core

import numpy as np

import pandas as pd

from datetime import datetime

from quants_core.stats import get_stats_all

coll = pd.read_excel(r'C:\Users\ntharani\Desktop\Data.xlsx', index_col=None, na_values=['NA'], usecols = 'A,D')

print(coll.head())

coll.set_index('Dates', inplace=True)

coll.index = pd.to_datetime(coll.index, format='%Y-%m-%dT%H:%M:%S.%fZ')

#print(coll)   # Returns are read and stored here

yy = get_stats_all(coll)

zz = yy.transpose()

zz = yy.values.T.flatten()

print(zz)

return zz.values.tolist()

",[Return])

 

The get_stats_all function returns a DataFrame with 1 row and 22 columns, The output is getting displayed on command line but somehow it is not getting displayed in Tableau views.

 

Any suggestions or improvements are appreciated. Thanks in advance.

 

PS: I cannot attach workbook due to confidentiality issues.

 

Message was edited by: Neha Tharani

6 risposte
  1. 8 ott 2018, 15:52

    Hi Neha,

     

    In your Python code you'd need to turn the data frame into a string of numbers (and potentially text) with defined separators, maybe something like:

     

    1.0~23~~3.14~~~red

     

    Then you'd need a set of N calculations (four in this example) to get each value, here's a screenshot:

     

    Hi Neha, In your Python code you'd need to turn the data frame into a string of numbers (and potentially text) with defined separators, maybe something like: 1.0~23~~3.

     

    As noted in the comment the formula is more complicated because (as of at least Tableau v2018.3) SPLIT, FINDNTH, and REGEX_EXTRACT_NTH aren't supported by table calculations (and the SCRIPT functions that Python is executed in are table calculations), vote up if you'd like to get that.

     

    Note that if the Python script is returning a changing number of variables in each run there's no automatic way to parse out into a variable number of calculated fields - you'll need to build as many calculations as you expect to have variables.

     

    I've attached a v10.5 workbook I used to make the screenshot above.

     

    Jonathan

     

    PS: I know this is really painful, I had a conversation with a Tableau developer last month and I know they are looking into this. I'll also forward this thread as an example.

0/9000

Hi

 

We are currently stuck with the Metadata API. We would like to query the Metadata API from a Python script but can't find any examples of how to do that. Unfortunately we can't implement GraphQL on the server we are using and would like to use a rest API approach, but I see that the Metadata API is GraphQL based. Does anyone know of a way to query the Metadata API from Python, and do we need to have GraphQL loaded on the server to hit the GraphQL API and return a JSON response? An example would help immensely.

 

We want to use the Metadata API to do dependency mapping of the database tables being used in our Tableau workbooks, so the Metadata comes in extremely handy for digging through custom SQL queries.

 

Thank you in advance for your assistance.

8 risposte
0/9000
Muteru Mwangi ha fatto una domanda in #Create

Hi Everyone,

We've just successfully upgraded our Production environment to Tableau Server 2019.1.2. Is there a way to disable Ask Data for all data sources on the Server?

Thanks.

Muteru Mwangi

20 risposte
  1. 6 ago 2019, 18:23

    Hey everyone,

     

    Thanks for the continued discussion. The TSM commands listed above to disable the UI for the input box are not an officially supported solution. Please use the following instructions to enable/disable Ask Data for Tableau versions 2019.1 and 2019.2 (as well as the minor versions of these releases).

     

    Enable Ask Data for Data Sources - Tableau

     

    This throttle is limited to the data source. However, we are actively working on the broader enable/disable settings (at the server and site level). I will share an update in a few weeks but we are targeting 2019.4 with this added capability.

     

    Thanks,

    Ruhaab Markas

    Sr. Product Manager - Ask Data

0/9000

Hi all,

I created slack bot using python sdk and my current situation is i was able to create multple buttons in single response and the buttons are name after items inside a python list. So I looped through the list and generated buttons. Now the problem is that I want a single @app.action listenr function which can handle all the these button clicks. How can i use create such function in slack bolt python

 

Given below is the code which is used to generate the buttons

@app.view("login_modal")

def handle_view_submission_events(ack, body, say, client):

  ack()

 

  username = body["view"]["state"]["values"]["Dn/DV"]["username_input"]["value"]

  password = body["view"]["state"]["values"]["FTQxY"]["password_input"]["value"]

  channel_id = body['user']['id']

 

  packet = {

    "userName": username,

    "password": password

  }

 

  url = f"{host}/api/login"

  response = requests.post(url=url, headers=headers, json=packet).json()

 

  if response != 'Please check your credentials':

    #print("body", body)

    cloud_types = response['items']['cloudTypes']

    buttons = [

      {

        "type": "button",

        "text": {"type": "plain_text", "text": cloud_type},

        "value": cloud_type,

        "action_id": f"cloud_type_selection_{i}"

      }

      for i, cloud_type in enumerate(cloud_types)

    ]

 

    say(

      blocks=[

        {

          "type": "section",

          "text": {"type": "mrkdwn", "text": f"Welcome to SkynetCloudKIT \n Dear user you are logged in as @{response['items']['userId']}"}

        },

        {

          "type": "section",

          "text": {"type": "mrkdwn", "text": f"Dear {response['items']['userId']} the registered clouds are ....! \n"}

        },

        {

          "type": "actions",

          "elements": buttons

        }

      ],

      channel=channel_id

    )

 

    # Store cloud types for later use

    #client.users_profile_set(

     # user=body["user"]["username"],

      #profile={

        #"cloud_types": cloud_types

      # }

    # )

  else:

    say(

      blocks=[

        {

          "type": "section",

          "text": {"type": "mrkdwn", "text": f"Login Failed \n Please check your credentials and try again! "}

        }

      ],

      channel=channel_id

    )

 

now i need a @app.action listner fuction for handling all these button clicks

Given below is the code I used for creating this type of function

@app.action("cloud_type_selection_*") # Handles all button clicks

def cloud_selection(body, ack, say, client):

  ack()

  print("here")

  cloud_type = body["actions"][0]["value"]

 

  # Retrieve stored cloud types

  user_profile = client.users_profile_get(user=body["user"]["id"])

  stored_cloud_types = user_profile["profile"]["cloud_types"]

 

  # Perform actions based on the selected cloud type (e.g., fetch data, display information)

  if cloud_type in stored_cloud_types:

    say(f"You selected: {cloud_type}")

  else:

    say(f"Invalid cloud type: {cloud_type}")

 

but im getting error saying

Unhandled request ({'type': 'block_actions', 'block_id': '0vR', 'action_id': 'cloud_type_selection_0'})

---

[Suggestion] You can handle this type of event with the following listener function:

 

@app.action("cloud_type_selection_0")

def handle_some_action(ack, body, logger):

  ack()

  logger.info(body)

4 risposte
  1. 20 set 2024, 20:12

    If you want to use the same action handler for all the buttons, then set the "value" parameter different for each button. That way you will get a different value returned in the payload, which you can then evaluate in your action handler.

     

    See here for parameters you can use with the buttons: https://api.slack.com/reference/block-kit/block-elements#button

0/9000

Hi everyone,

 

I need to get page-based user view counts using the Python rest api. Can you support me on this issue?

2 risposte
  1. 25 set 2024, 16:53

    @Serkan Arslan​ 

    Hi, in this case you may use Tableau Server Client:

    import tableauserverclient as TSC

    import csv

     

    # server admin creds

    HOST = "https://prod-useast-b.online.tableau.com/"

    TOKEN_NAME = "Test"

    TOKEN_VALUE = "cjcvCg==:45pE9"

    CONTENT_URL = "yoursite"

     

    tableau_auth = TSC.PersonalAccessTokenAuth(TOKEN_NAME, TOKEN_VALUE, site_id=CONTENT_URL)

    server = TSC.Server(HOST, use_server_version=True)

     

     

    #Create the csv file and open it in write mode

    f = open('views.csv', 'w', encoding='UTF8', newline='')

     

    #delimiter with semicolon if need change to comma, and write header

    writer = csv.writer(f, delimiter=";")

    header = ['content URL','name','Owner_id','total_views']

    writer.writerow(header)

     

    today_date = datetime.now(timezone.utc)

     

    with server.auth.sign_in(tableau_auth):

    for view in TSC.Pager(server.views,usage=True):

    row=[view.content_url,view.name,view.owner_id,view.total_views]

    #print(view.conten_url,view.name,view.owner_id,view.total_views)

    #write the row

    writer.writerow(row)

    #Close file connection and sign out

    f.close()

    server.auth.sign_out()

    To use this code, you will need a PAT:

    https://help.tableau.com/current/pro/desktop/en-us/useracct.htm#create-a-personal-access-token

     

    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