8000 Jac/headers (#1117) · LehmD/server-client-python@bf6a0e6 · GitHub
[go: up one dir, main page]

Skip to content

Commit bf6a0e6

Browse files
authored
Jac/headers (tableau#1117)
* ssl-verify is an option, not a header
1 parent f653e15 commit bf6a0e6

File tree

4 files changed

+80
-30
lines changed

4 files changed

+80
-30
lines changed

samples/create_group.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def main():
4646
logging.basicConfig(level=logging_level)
4747

4848
tableau_auth = TSC.PersonalAccessTokenAuth(args.token_name, args.token_value, site_id=args.site)
49-
server = TSC.Server(args.server, use_server_version=True)
49+
server = TSC.Server(args.server, use_server_version=True, http_options={"verify": False})
5050
with server.auth.sign_in(tableau_auth):
5151
# this code shows 3 different error codes that mean "resource is already in collection"
5252
# 409009: group already exists on server

tableauserverclient/server/endpoint/endpoint.py

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@
1111
NonXMLResponseError,
1212
EndpointUnavailableError,
1313
)
14-
from .. import endpoint
1514
from ..query import QuerySet
1615
from ... import helpers
16+
from ..._version import get_versions
17+
18+
__TSC_VERSION__ = get_versions()["version"]
19+
del get_versions
1720

1821
logger = logging.getLogger("tableau.endpoint")
1922

@@ -22,34 +25,25 @@
2225
XML_CONTENT_TYPE = "text/xml"
2326
JSON_CONTENT_TYPE = "application/json"
2427

28+
USERAGENT_HEADER = "User-Agent"
29+
2530
if TYPE_CHECKING:
2631
from ..server import Server
2732
from requests import Response
2833

2934

30-
_version_header: Optional[str] = None
31-
32-
3335
class Endpoint(object):
3436
def __init__(self, parent_srv: "Server"):
35-
global _version_header
3637
self.parent_srv = parent_srv
3738

3839
@staticmethod
3940
def _make_common_headers(auth_token, content_type):
40-
global _version_header
41-
42-
if not _version_header:
43-
from ..server import __TSC_VERSION__
44-
45-
_version_header = __TSC_VERSION__
46-
4741
headers = {}
4842
if auth_token is not None:
4943
headers["x-tableau-auth"] = auth_token
5044
if content_type is not None:
5145
headers["content-type"] = content_type
52-
headers["User-Agent"] = "Tableau Server Client/{}".format(_version_header)
46+
headers["User-Agent"] = "Tableau Server Client/{}".format(__TSC_VERSION__)
5347
return headers
5448

5549
def _make_request(
@@ -62,9 +56,9 @@ def _make_request(
6256
parameters: Optional[Dict[str, Any]] = None,
6357
) -> "Response":
6458
parameters = parameters or {}
65-
parameters.update(self.parent_srv.http_options)
6659
if "headers" not in parameters:
6760
parameters["headers"] = {}
61+
parameters.update(self.parent_srv.http_options)
6862
parameters["headers"].update(Endpoint._make_common_headers(auth_token, content_type))
6963

7064
if content is not None:

tableauserverclient/server/server.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,6 @@
3737
from ..namespace import Namespace
3838

3939

40-
from .._version import get_versions
41-
42-
__TSC_VERSION__ = get_versions()["version"]
43-
del get_versions
44-
4540
_PRODUCT_TO_REST_VERSION = {
4641
"10.0": "2.3",
4742
"9.3": "2.2",
@@ -51,7 +46,6 @@
5146
}
5247
minimum_supported_server_version = "2.3"
5348
default_server_version = "2.3"
54-
client_version_header = "X-TableauServerClient-Version"
5549

5650

5751
class Server(object):
@@ -98,23 +92,29 @@ def __init__(self, server_address, use_server_version=False, http_options=None):
9892
# must set this before calling use_server_version, because that's a server call
9993
if http_options:
10094
self.add_http_options(http_options)
101-
self.add_http_version_header()
10295

10396
if use_server_version:
10497
self.use_server_version()
10598

106-
def add_http_options(self, options_dict):
107-
self._http_options.update(options_dict)
108-
if options_dict.get("verify") == False:
99+
def add_http_options(self, option_pair: dict):
100+
if not option_pair:
101+
# log debug message
102+
return
103+
if len(option_pair) != 1:
104+
raise ValueError(
105+
"Update headers one at a time. Expected type: ",
106+
{"key": 12}.__class__,
107+
"Actual type: ",
108+
option_pair,
109+
option_pair.__class__,
110+
)
111+
self._http_options.update(option_pair)
112+
if "verify" in option_pair.keys() and self._http_options.get("verify") is False:
109113
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
110-
111-
def add_http_version_header(self):
112-
if not self._http_options[client_version_header]:
113-
self._http_options.update({client_version_header: __TSC_VERSION__})
114+
# would be nice if you could turn them back on
114115

115116
def clear_http_options(self):
116117
self._http_options = dict()
117-
self.add_http_version_header()
118118

119119
def _clear_auth(self):
120120
self._site_id = None

test/http/test_http_requests.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import tableauserverclient as TSC
2+
import unittest
3+
from requests.exceptions import MissingSchema
4+
5+
6+
class ServerTests(unittest.TestCase):
7+
def test_init_server_model_empty_throws(self):
8+
with self.assertRaises(TypeError):
9+
server = TSC.Server()
10+
11+
def test_init_server_model_bad_server_name_complains(self):
12+
# by default, it will just set the version to 2.3
13+
server = TSC.Server("fake-url")
14+
15+
def test_init_server_model_valid_server_name_works(self):
16+
# by default, it will just set the version to 2.3
17+
server = TSC.Server("http://fake-url")
18+
19+
def test_init_server_model_valid_https_server_name_works(self):
20+
# by default, it will just set the version to 2.3
21+
server = TSC.Server("https://fake-url")
22+
23+
def test_init_server_model_bad_server_name_not_version_check(self):
24+
# by default, it will just set the version to 2.3
25+
server = TSC.Server("fake-url", use_server_version=False)
26+
27+
def test_init_server_model_bad_server_name_do_version_check(self):
28+
with self.assertRaises(MissingSchema):
29+
server = TSC.Server("fake-url", use_server_version=True)
30+
31+
def test_init_server_model_bad_server_name_not_version_check_random_options(self):
32+
# by default, it will just set the version to 2.3
33+
server = TSC.Server("fake-url", use_server_version=False, http_options={"foo": 1})
34+
35+
def test_init_server_model_bad_server_name_not_version_check_real_options(self):
36+
# by default, it will attempt to contact the server to check it's version
37+
server = TSC.Server("fake-url", use_server_version=False, http_options={"verify": False})
38+
39+
def test_http_options_skip_ssl_works(self):
40+
http_options = {"verify": False}
41+
server = TSC.Server("http://fake-url")
42+
server.add_http_options(http_options)
43+
44+
# ValueError: dictionary update sequence element #0 has length 1; 2 is required
45+
def test_http_options_multiple_options_fails(self):
46+
http_options_1 = {"verify": False}
47+
http_options_2 = {"birdname": "Parrot"}
48+
server = TSC.Server("http://fake-url")
49+
with self.assertRaises(ValueError):
50+
server.add_http_options([http_options_1, http_options_2])
51+
52+
# TypeError: cannot convert dictionary update sequence element #0 to a sequence
53+
def test_http_options_not_sequence_fails(self):
54+
server = TSC.Server("http://fake-url")
55+
with self.assertRaises(ValueError):
56+
server.add_http_options({1, 2, 3})

0 commit comments

Comments
 (0)
0