1 2 Previous Next 25 Replies Latest reply on Feb 18, 2015 3:26 PM by Jeff D

    Can get trusted ticket via Python but not get views

    Jonathan Drummey

      Hi,

       

      I'm running Python 3.3.3 on Windows Server 2008 with Tableau 8.3.

       

      I've followed the instructions for adding trusted hosts, retrieving a ticket, and retrieving views. The following chunk of code is able to get a trusted ticket, but as soon as I attempt to use the ticket in a URL in the code immediately after I either get a Tableau login page (when using the Python script) or a "Could not locate unexpired trusted ticket" error from Tableau Server (when I paste the ticket URL into a web browser).

       

      On the browser side, I followed the instructions in http://kb.tableau.com/articles/knowledgebase/testing-trusted-authentication?lang=en-us, made sure that cookies are allowed, and still get the same "Could not locate unexpired trusted ticket" error.

       

      However, I don't really care about the web browser error, it's being able to retrieve views via Python that I'm more interested in. Anyone have any ideas? The python code I've been using is below:

       

      import requests
      import sys
      import urllib
      
      # replace these with configData
      tableauServer = 'http://localhost/'
      tableauUsername = 'jtdrummey'
      workbookView = 'OperationalExcellenceHuddleBoard/dataDateTime'
      worksheetSuffix = '.csv'
      
      # getting trusted authentication for Tableau
      # see http://onlinehelp.tableau.com/current/server/en-us/trusted_auth.htm
      # for details on how to set up 
      
      wgserverURL = tableauServer + 'trusted/'
      r = requests.post(wgserverURL, data={'username': tableauUsername})
      
      # status_code has the response code, text has the ticket string
      if r.status_code == 200:
          if r.text != '-1':
              ticketID = r.text
              print("ticket # is", ticketID)
          else:
              print("Tableau Server could not issue trusted ticket, for more information see \n ...ProgramData\Tableau\Tableau Server\data\tabsvc\logs\wgserver\production*.log and \n ...ProgramData\Tableau\Tableau Server\data\tabsvc\logs\vizqlserver\vizql*.log \nAlso check http://onlinehelp.tableau.com/current/server/en-us/trusted_auth_trouble_1return.htm")
              sys.exit()
      else:
          print('Could not get trusted ticket with status code',str(r.status_code))
      
      
      # This Tableau Public URL works fine
      #url = 'https://public.tableausoftware.com/views/tmpDate/Sheet1.csv?:embed=n&:showVizHome=no'
      
      ########## PROBLEM ################
      # This URL with the trusted ticket that was just issued returns one of two different things:
      # 1. when the Python script is run returns the HTML for the Tableau login
      # 2. when I enter the URL on Tableau Server I get an error "Could not locate unexpired trusted ticket [ticketID]"
      url = wgserverURL + ticketID + '/views/' + workbookView + worksheetSuffix
      print(url)
      
      # print out 1st 300 characters of output, this should be a csv file
      f = urllib.request.urlopen(url)
      print(f.read(300).decode('utf-8'))
      
      # store results in HTML file for testing purposes
      g = open('result.html','w')
      g.write(f.read().decode('utf-8'))
      

       

      Jonathan

        • 1. Re: Can get trusted ticket via Python but not get views
          Russell Christopher

          Heya

           

          sleepless in Singapore right now!

           

          as written, your  code is getting a trusted tick from the default tableau site. Are you retrieving a view from the default site, too? You must, else your ticket won't work  the error message about unexpired ticket is a symptom of this issue.

           

          sorry for the terrible capitalization.. iPad is acting up.

          1 of 1 people found this helpful
          • 2. Re: Can get trusted ticket via Python but not get views
            Jonathan Drummey

            Hi Russell,

             

            I was hoping you'd take a look at this!

             

            Yes, I'm using the default site for both, I never set up any sites on our server.

             

            The Python code is running on the localhost and requesting from the localhost (default site). In my web browser tests, I ran the Python code on localhost to get the ticket number and then plugged the result of print(url) into a browser also running on localhost.

             

            Does that give you any hints?

             

            Jonathan

            • 3. Re: Can get trusted ticket via Python but not get views
              Russell Christopher

              Your test web page mentioned in the article fails, too? In other words you can always retrieve a ticket, but then can't actually redeem it? That's odd. Normally this breaks when retrieving a ticket if it breaks at all. You're special.

               

              bout my suggestion would be o use pgadmin3 to connect to Postgres's trusted_tickets table and what the values that get deposited in it while running the first part of your code which requests tickets. Then copy/paste a value or two right out of the table and add it to a request in the browser directly,,,see if it works,

               

              only nly other things that I can think of is someone set an unnaturally low expiration value on the tickets themselves or maybe extended ip checking for tickets is turned on,,,that could get in the way depending on how the IP address on the client is getting resolved...maybe an IP6 and/or multi-NiC thing,

              1 of 1 people found this helpful
              • 4. Re: Can get trusted ticket via Python but not get views
                Jonathan Drummey

                Yep, I can always retrieve a ticket and can't redeem it...I don't want to be special!!!

                 

                I'll try connecting to Postgres and see what happens. I used hostnames to avoid any IP address issues (I don't have control over the hardware, just Tableau), would that play into this? I've been assuming since I could retrieve the ticket that the problem was further downstream, I'll try adding the IP address directly to the server.

                 

                Jonathan

                • 5. Re: Can get trusted ticket via Python but not get views
                  Robin Cottiss

                  Jonathan, I tested your code on my local server. I think it is related to you using localhost as the server. localhost is not trusted by default but 127.0.0.1 is.Try 127.0.0.1 in your url or add localhost or ::1 as a trusted host. I added both localhost and ::1 (because ::1 comes out in the error log). My test environment happens to be v9 beta  I added the trusted hosts to both wgserver and vizportal.

                   

                  tabadmin set vizportal.trusted_hosts "::1,localhost"

                  tabadmin set wgserver.trusted_hosts "::1,localhost"


                  Robin

                  1 of 1 people found this helpful
                  • 6. Re: Can get trusted ticket via Python but not get views
                    Jonathan Drummey

                    Thanks for replying, Robin! (And you, too, Russell!)

                     

                    I'm not able to use ::1, whenever I try it I get:

                     

                    d:\Tableau\Tableau Server\8.3\bin>tabadmin set wgserver.trusted_hosts "::1"
                    
                    d:\Tableau\Tableau Server\8.3\bin>tabadmin config
                      *** WARNING: Invalid value(s) found in: 'd:/Tableau/Tableau Server/config/tabs
                    vc.yml'
                    
                    The value of ':1' for 'wgserver.trusted_hosts' will be ignored. Value 'wgserver.
                    trusted_hosts' must be a comma-separated list of valid machine(s) each as either
                    a DNS name (eg: tabserver.yourdomain.com), IPv4 address (eg: 192.168.0.100), or
                    IPv6 address (eg: FE00::1) Configuration used default:
                      ***
                    Configuration will be completed with default settings for listed options.
                    

                     

                    I had previously tried localhost, and I just tried the following:

                     

                    tabadmin set wgserver.trusted_hosts "127.0.0.1, 172.18.65.31, localhost, smmc-as04, tableau, smmc-as04.smmc.local"
                    

                     

                    And every single one of these gives the same problem - the ticket is returned, but then querying for the view fails. Any other thoughts?

                     

                    Jonathan

                    • 7. Re: Can get trusted ticket via Python but not get views
                      Russell Christopher

                      if this were the issue I'd think that retrieving a ticket would fail too -- name resolution is name resolution and Tableau server would return -1 on the request for the ticket...

                       

                      the the fact that localhost and the ip are being mentioned in trusted_hosts should prevent this issue....

                       

                      JOnathan, can you eyeball the request coming in via the Apache logs? It'll show the IP address of the request as we see it, Also, are you familiar with fiddler or Charles? Watching what happens from one of these tools could. behelpful

                       

                      **** ipad

                      1 of 1 people found this helpful
                      • 8. Re: Can get trusted ticket via Python but not get views
                        Robin Cottiss

                        Sorry I confused things with the IPV6. V9 allowed me to add it.

                         

                        Once you get a valid ticket the next problem seems to be that you are not passing the cookie on to the final URL. what happens is that when you call the url with the trusted ticket it responds with 302 redirect with a session cookie set. I believe you are not passing the session cookie back so you get a login page. I am not a Python expert and I am using Python 2.7 so I am still working out how to send the cookie. I think I might need urllib2 in Python 2.7. It looks like urllib in Python 3 can allow you to follow the redirect with the cookie but I am not sure of the exact code.

                         

                        Robin

                        1 of 1 people found this helpful
                        • 9. Re: Can get trusted ticket via Python but not get views
                          Robin Cottiss

                          Here is some Python 2.7 code that works. It might help get the Python 3 code working:

                           

                          import requests  
                          import sys  
                          #import urllib  
                          import cookielib, urllib2
                            
                          # replace these with configData  
                          tableauServer = 'http://127.0.0.1/'  
                          tableauUsername = 'Robin'  
                          workbookView = 'WorldIndicators/GDPpercapita'  
                          worksheetSuffix = '.csv'  
                            
                          # getting trusted authentication for Tableau  
                          # see http://onlinehelp.tableau.com/current/server/en-us/trusted_auth.htm  
                          # for details on how to set up   
                            
                          wgserverURL = tableauServer + 'trusted/'  
                          r = requests.post(wgserverURL, data={'username': tableauUsername})  
                          print('wgserverURL: ',wgserverURL)
                          print('r.status_code: ',str(r.status_code))
                          print(type(r.status_code))
                          
                          
                            
                          # status_code has the response code, text has the ticket string  
                          if r.status_code == 200:  
                              if r.text != '-1':  
                                  ticketID = r.text  
                                  print("ticket # is", ticketID)  
                              else:  
                                  print("Tableau Server could not issue trusted ticket, for more information see \n ...ProgramData\Tableau\Tableau Server\data\\tabsvc\logs\wgserver\production*.log and \n ...ProgramData\Tableau\Tableau Server\data\\tabsvc\logs\\vizqlserver\\vizql*.log \nAlso check http://onlinehelp.tableau.com/current/server/en-us/trusted_auth_trouble_1return.htm")  
                                  sys.exit()  
                          else:  
                              print('Could not get trusted ticket with status code',str(r.status_code))  
                            
                            
                          # This Tableau Public URL works fine  
                          #url = 'https://public.tableausoftware.com/views/tmpDate/Sheet1.csv?:embed=n&:showVizHome=no'  
                            
                          ########## PROBLEM ################  
                          # This URL with the trusted ticket that was just issued returns one of two different things:  
                          # 1. when the Python script is run returns the HTML for the Tableau login  
                          # 2. when I enter the URL on Tableau Server I get an error "Could not locate unexpired trusted ticket [ticketID]"  
                          url = wgserverURL + ticketID + '/views/' + workbookView + worksheetSuffix  
                          print(url)  
                            
                          # print out 1st 300 characters of output, this should be a csv file  
                          #f = urllib.request.urlopen(url)  
                          cj = cookielib.CookieJar()
                          opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
                          f = opener.open(url)
                          
                          
                          #f = urllib.urlopen(url)  
                          print(f.read(300).decode('utf-8'))  
                          
                          
                          
                          # store results in HTML file for testing purposes  
                          g = open('result.html','w')  
                          g.write(f.read().decode('utf-8'))  
                          
                          1 of 1 people found this helpful
                          • 10. Re: Can get trusted ticket via Python but not get views
                            Jeff D

                            Hi Jonathan, I think Robin is on the right track with the cookie jar.  If you use a redeemed ticket without cookies, it wouldn't be surprising to get an error.  For a valid browser test, exit immediately after you get the ticket and enter the URL in the browser.

                            1 of 1 people found this helpful
                            • 11. Re: Can get trusted ticket via Python but not get views
                              Jonathan Drummey

                              I have a solution now. I'd also reached out to Tableau tech support and they pointed out some extra conditions that are required for trusted authentication to work:

                               

                              1. The ticket being utilized for access is less than 180 seconds old and only being utilized for a single session and only for access to the view which it was originally requested for.
                              2. The IP of the workstation calling the URL is whitelisted if using: wgserver.extended_trusted_ip_checking true
                              3. If a proxy, web filter, or other network optimization solution that changes the apparent IP address of the trusted host making the request for the trusted ticket, the request will fail.

                               

                              The Python code I'd posted was failing #1 because it was retrieving the ticket and redeeming it, then I'd manually copy the ticket and paste it into a web browser, that 2nd redemption request from a 2nd session would make the browser fail. When I had the Python code just retrieve the ticket and then did the manual paste into the browser, everything worked. So now I was sure that I could retrieve a ticket and redeem it.

                               

                              Now for the next part. I was looking at the 2.7 code that Robin posted and trying to adapt it to 3.3. Being so new to Python I was having some problems trying to figure out what to use in place of the deprecated cookielib module, and in my web searches I came across people suggesting to the requests module, which I was already using for the ticket retrieval (based on other code I'd found on the web). So I did some digging to set up a cookie and then do r = requests.get(url, cookie) and that didn't work, and then I went back to the sample code in C:\Program Files\Tableau\Tableau Server\8.3\extras\embedding as referenced in Get a Ticket from Tableau Server. Looking at the PHP and Ruby code made me think that a cookie wasn't actually necessary, since neither of them referenced cookies at all.

                               

                              So I tried just r = requests.get(url) and it works!

                               

                              Here's the working code:

                               

                              import requests
                              import sys
                              
                              # replace these with configData
                              tableauServer = 'http://tableau/'
                              tableauUsername = 'jtdrummey'
                              workbookView = 'SMHCPhysicianServicesProvidersforPHO/ProviderList'
                              worksheetSuffix = '.csv'
                              
                              # getting trusted authentication for Tableau
                              # see http://onlinehelp.tableau.com/current/server/en-us/trusted_auth.htm
                              # for details on how to set up 
                              
                              wgserverURL = tableauServer + 'trusted/'
                              r = requests.post(wgserverURL, data={'username': tableauUsername})
                              
                              # status_code has the response code, text has the ticket string
                              if r.status_code == 200:
                                  if r.text != '-1':
                                      ticketID = r.text
                                  else:
                                      print("Tableau Server could not issue trusted ticket, for more information see \n ...ProgramData\Tableau\Tableau Server\data\tabsvc\logs\wgserver\production*.log and \n ...ProgramData\Tableau\Tableau Server\data\tabsvc\logs\vizqlserver\vizql*.log \nAlso check http://onlinehelp.tableau.com/current/server/en-us/trusted_auth_trouble_1return.htm")
                                      sys.exit()
                              else:
                                  print('Could not get trusted ticket with status code',str(r.status_code))
                              
                              url = wgserverURL + ticketID + '/views/' + workbookView + worksheetSuffix
                              print(url)
                              
                              r = requests.get(url)
                              print(r.text)
                              

                               

                              Russell, Robin, and Jeff, thanks for your help!

                              1 of 1 people found this helpful
                              • 12. Re: Can get trusted ticket via Python but not get views
                                Jeff D

                                HI Jonathan, glad you found a solution!

                                 

                                There are two things you mentioned that don't sound quite right.

                                 

                                - After a ticket has been redeemed, it can be used for more than one view, and it can be used over a longer period of time.

                                 

                                - Cookies are required.  The python "requests" package is considered to be "http request processing done right".  True in this case, as it is handling cookies for you automatically.

                                1 of 1 people found this helpful
                                • 13. Re: Can get trusted ticket via Python but not get views
                                  Jonathan Drummey

                                  Hi Jeff,

                                   

                                  I've been on your side of the "that doesn't sound right, there's something deeper going on here..." question multiple times and I'm happy to explore this further if you are. Responding to both your comments:

                                   

                                  1. I've tested where suing a for loop I've requested the same view multiple times on the same ticket and (separately) different views on the same ticket and I get 403 errors every time. So it doesn't seem like a timeout would be the problem, would it be something else?

                                   

                                  2. How would I see the cookies in the requests module? After both retrieving & redeeming the ticket I've tried:

                                   

                                  for cookie in r.cookies
                                      print(cookie)
                                  

                                   

                                  And in both cases seen nothing. And it seems like the r = requests.get(url) isn't sending any cookie, so where would the cookie be?

                                   

                                  Jonathan

                                  • 14. Re: Can get trusted ticket via Python but not get views
                                    Jeff D

                                    Hi Jonathan, when you tested multiple retrievals with the same ticket, did the URL contain the ticket number?  It shouldn't.  The redeemed ticket is replaced by a cookie and the URL is the standard URL (as if you were logged on).

                                    1 2 Previous Next