1
1
####
2
- # This script demonstrates how to query for permissions using TSC
2
+ # This script is for smoke testing VizQL Data Service.
3
3
# To run the script, you must have installed Python 3.7 or later.
4
4
#
5
- # Example usage: 'python query_permissions.py -s https://10ax.online.tableau.com --site
6
- # devSite123 -u tabby@tableau.com b4065286-80f0-11ea-af1b-cb7191f48e45'
5
+ # Example usage: 'python vizql_data_service_smoke_test_cap.py --token-name token
6
+ # --token-value DUCg0rbPROuuAMz9rDI4+Q==:OM2SzwPVK7dNITHo4nfUgsTZvVBQj8iQ
7
+ # --server stage-dataplane7.online.vnext.tabint.net
8
+ # --site hbistagedp7
9
+ # --datasouce-luid ebe79f30-bdff-425a-8a9c-3cda79dbbbfd
10
+ # --cap 2000'
11
+
7
12
####
8
13
9
14
import argparse
10
15
import logging
11
16
import requests
12
17
import json
18
+ import xml .etree .ElementTree as ET
19
+
20
+ def parse_token_from_response (xml_response ):
21
+ namespace = {'ns' : 'http://tableau.com/api' }
22
+ root = ET .fromstring (xml_response )
23
+
24
+ # Find the token attribute in the credentials tag
25
+ credentials = root .find ('ns:credentials' , namespace )
26
+ if credentials is not None :
27
+ token = credentials .get ('token' )
28
+ return token
29
+ else :
30
+ raise ValueError ("Token not found in the XML response." )
31
+
32
+
33
+ def sign_in (args ):
34
+ url = f"https://{ args .server } /api/3.22/auth/signin"
35
+
36
+ payload = json .dumps ({
37
+ "credentials" : {
38
+ "personalAccessTokenName" : args .token_name ,
39
+ "personalAccessTokenSecret" : args .token_value ,
40
+ "site" : {
41
+ "contentUrl" : args .site
42
+ }
43
+ }
44
+ })
45
+ headers = {
46
+ 'Content-Type' : 'application/json'
47
+ }
13
48
14
- import tableauserverclient as TSC
15
-
49
+ response = requests .request ("POST" , url , headers = headers , data = payload )
50
+ auth_token = parse_token_from_response (response .text )
51
+ return auth_token
16
52
17
53
def main ():
18
54
parser = argparse .ArgumentParser (description = "Query permissions of a given resource." )
19
- # Common options; please keep those in sync across all samples
20
55
parser .add_argument ("--server" , "-s" , help = "server address" )
21
56
parser .add_argument ("--site" , "-S" , help = "site name" )
22
57
parser .add_argument ("--token-name" , "-p" , help = "name of the personal access token used to sign into the server" )
@@ -28,39 +63,46 @@ def main():
28
63
default = "error" ,
29
64
help = "desired logging level (set to error by default)" ,
30
65
)
31
- parser .add_argument ("resource_id" )
66
+ parser .add_argument ("--datasource-luid" , "-ds" , help = "The luid of the datasource to query" , required = True )
67
+ parser .add_argument ("--cap" , "-c" , type = int , help = "The cap on the current cloud site" , required = True )
68
+
69
+ args = parser .parse_args ()
32
70
33
71
# Set logging level based on user input, or error by default
34
72
logging_level = getattr (logging , args .logging_level .upper ())
35
73
logging .basicConfig (level = logging_level )
36
74
37
75
# Sign in
38
- tableau_auth = TSC .PersonalAccessTokenAuth (args .token_name , args .token_value , site_id = args .site )
39
- server = TSC .Server (args .server , use_server_version = True )
40
-
41
- with server .auth .sign_in (tableau_auth ):
42
- endpoint = server .datasources
43
-
44
- # Get the resource by its ID
45
- resource = endpoint .get_by_id (args .resource_id )
46
- print (server )
76
+ auth_token = sign_in (args )
47
77
78
+ url = "https://" + args .server + "/api/v1/vizql-data-service/read-metadata"
48
79
49
- url = "https://" + args .server + "/api/v1/vizql-data-service/read-metadata"
50
-
51
- payload = "{\n \" datasource\" : {\n \" datasourceLuid\" : \" " + args .resource_id + "\" \n },\n \" options\" : {\n \" debug\" : true\n }\n }"
52
- headers = {
53
- 'X-Tableau-Auth' : server .auth_token ,
54
- 'Content-Type' : 'application/json' ,
80
+ payload = json .dumps ({
81
+ "datasource" : {
82
+ "datasourceLuid" : args .datasource_luid
55
83
}
84
+ })
85
+ headers = {
86
+ 'X-Tableau-Auth' : auth_token ,
87
+ 'Content-Type' : 'application/json' ,
88
+ }
56
89
57
- response = requests .request ("POST" , url , headers = headers , data = payload )
90
+ # Test cap limit
91
+ for i in range (args .cap + 1 ):
92
+ response = requests .post (url , headers = headers , data = payload )
93
+ status_code = response .status_code
58
94
59
- print (response .text )
95
+ if i < args .cap and status_code != 200 :
96
+ response_message = response .text
97
+ exceptionMsg = f"Unexpected status code for call { i + 1 } : { status_code } (Expected: 200). Response message: { response_message } " ;
98
+ raise Exception (exceptionMsg )
99
+ elif i >= args .cap and status_code != 429 :
100
+ exceptionMsg = f"Call not rate limited: Unexpected status code for call { i + 1 } : { status_code } (Expected: 429)" ;
101
+ raise Exception (exceptionMsg )
60
102
103
+ logging .info (f"Call { i + 1 } /{ args .cap } : Status Code { status_code } " )
61
104
105
+ print (f"Completed { args .cap } calls to VizQL Data Service." )
62
106
63
107
if __name__ == "__main__" :
64
108
main ()
65
-
66
-
0 commit comments