QBoard » Advanced Visualizations » Viz - Tableau » Query tableau workbooks using tableau Rest API

Query tableau workbooks using tableau Rest API

  • I am new to API coding and working on a module which signs in to Tableau Server and gets the list of workbooks stored in a site. The code is to be written in C# using the Tableau Rest API.

    I was able to sign in to Tableau server successfully using the Rest API. However, I was not able to query the workbooks. Below is my code.

    class Program
        {
            static HttpClient client = new HttpClient();
    
    
            public static string site_id { get; set;}
            public static string token { get; set; }
            static void Main(string[] args)
            {
                CallWebAPIAsync().Wait();
            }
    
            static async Task CallWebAPIAsync()
            {
                using (var client = new HttpClient())
                {
                    client.Timeout = TimeSpan.FromMilliseconds(Timeout.Infinite);
                    client.BaseAddress = new Uri("https://my server url.com");
                    client.DefaultRequestHeaders.Accept.Clear();
                    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
                    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/octet-stream"));
                    SignIn(client);
                    Workbooks(client, site_id, token);
                }
    
                Console.Read();
            }
    
            public class CustomXmlMediaTypeFormatter : XmlMediaTypeFormatter
            {
                public CustomXmlMediaTypeFormatter()
                {
                    UseXmlSerializer = true;
                    WriterSettings.OmitXmlDeclaration = false;
                }
            }
            public static tableauCredentialsType SignIn(HttpClient client)
            {
                var name = "Administrator";
                var password = "password";
                var site = "";
    
                var tableauCredentialsType = new tsRequest()
                {
                    Item = new tableauCredentialsType
                    {
                        name = name,
                        password = password,
                        site = new siteType() { contentUrl = site }
                    }
                };
    
                var httpContent = new ObjectContent<tsRequest>(tableauCredentialsType, new CustomXmlMediaTypeFormatter());
    
                var httpResponseMessage = client.PostAsync("/api/3.2/auth/signin", httpContent).Result;
    
                if (httpResponseMessage.StatusCode != System.Net.HttpStatusCode.OK)
                    throw new Exception(string.Format("Unable to login to the server", site, name));
    
                var responseLogin = httpResponseMessage.Content.ReadAsAsync<tsResponse>(new List<MediaTypeFormatter>() { new CustomXmlMediaTypeFormatter() }).Result;
    
                var resultTableauCredentialsType = ((tableauCredentialsType)responseLogin.Items[0]);
    
                site_id = resultTableauCredentialsType.site.id;
    
                token = resultTableauCredentialsType.token;
    
                return resultTableauCredentialsType;
    
            }
    
            public static IList<workbookType> Workbooks(HttpClient client, string siteid, string auth_token, int pageSize = 100, int pageNumber =1)
            {
                IList<workbookType> results = new List<workbookType>();
    
                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("x-tableau-auth", auth_token);
               var query = client.GetAsync(string.Format("/api/3.2/sites/{0}/workbooks", siteid, pageSize, pageNumber)).Result;
    
                if(query.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    var result = query.Content.ReadAsAsync<tsResponse>(new List<MediaTypeFormatter>() { new CustomXmlMediaTypeFormatter() }).Result;
    
                    var pagination = (paginationType)result.Items[0];
    
                    var workbooks = ((workbookListType)result.Items[1]).workbook.AsEnumerable();
    
                    for (int i=2; i < pageNumber; i++)
                    {
                        query = client.GetAsync(string.Format("/api/3.2/sites/{0}/workbooks", siteid, pageSize, i)).Result;
    
                        if(query.StatusCode == System.Net.HttpStatusCode.OK)
                        {
                            result = query.Content.ReadAsAsync<tsResponse>(new List<MediaTypeFormatter>() { new CustomXmlMediaTypeFormatter() }).Result;
    
                            workbooks = workbooks.Concat(((workbookListType)result.Items[1]).workbook.AsEnumerable());
                        }
                    }
    
                    results = workbooks.ToList();
                }
    
                return results;
            }
        }
    

     

    When I try to run the Workbooks function in the above code I am getting 401-Unauthorized error. I came to know that I need to pass the X-tableau_auth so that I will have the authentication done while querying for the workbooks. However, I was not able to get that properly.

    Can anyone help me with this?

      November 15, 2021 12:44 PM IST
    0
  • The header information can be passed using the DefaultRequestHeaders Add method.

    You can try something like

    client.DefaultRequestHeaders.Add("x-tableau-auth", "tokenvalue");
    

     

    Also the api parameters is incorrect. You can refer to the API guide provided by Tableau

     
      November 19, 2021 12:11 PM IST
    0
  • Did you check the Url that you're using to fetch the list of workbooks? I checked with Tableau's API documentation, the Url format looks different, try updating your code

    string.Format("/api/{0}/sites/site-id/workbooks", siteid, pageSize, i)
    

     

    to

    string.Format("/api/3.4/sites/{0}/workbooks", siteid)
    

     

    Here I assumed you're using 3.4 version api.

    I'd also recommend using some Rest Clients to test these Apis before you code.

      November 23, 2021 12:59 PM IST
    0
  • With the Tableau Server REST API you can manage and change Tableau Server, Tableau Online site, and Prep Conductor resources programmatically, using HTTP. The API gives you simple access to the functionality behind Tableau data sources, projects, workbooks, site users, sites, flows, and more. You can use this access to create your own custom applications or to script interactions with Tableau resources.

      December 21, 2021 1:54 PM IST
    0