8000 add query-tagging attribute to connection by jacalata · Pull Request #1202 · tableau/server-client-python · GitHub
[go: up one dir, main page]

Skip to content

add query-tagging attribute to connection #1202

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion tableauserverclient/models/connection_item.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import logging
from typing import List, Optional

from defusedxml.ElementTree import fromstring

from .connection_credentials import ConnectionCredentials
from .property_decorators import property_is_boolean


class ConnectionItem(object):
Expand All @@ -17,6 +19,7 @@ def __init__(self):
self.server_port: Optional[str] = None
self.username: Optional[str] = None
self.connection_credentials: Optional[ConnectionCredentials] = None
self._query_tagging: Optional[bool] = None

@property
def datasource_id(self) -> Optional[str]:
Expand All @@ -34,6 +37,22 @@ def id(self) -> Optional[str]:
def connection_type(self) -> Optional[str]:
return self._connection_type

@property
def query_tagging(self) -> Optional[bool]:
return self._query_tagging

@query_tagging.setter
@property_is_boolean
def query_tagging(self, value: Optional[bool]):
# if connection type = hyper, Snowflake, or Teradata, we can't change this value: it is always true
if self._connection_type in ["hyper", "snowflake", "teradata"]:
logger = logging.getLogger("tableauserverclient.models.connection_item")
logger.debug(
"Cannot update value: Query tagging is always enabled for {} connections".format(self._connection_type)
)
return
self._query_tagging = value

def __repr__(self):
return "<ConnectionItem#{_id} embed={embed_password} type={_connection_type} username={username}>".format(
**self.__dict__
Expand All @@ -52,6 +71,7 @@ def from_response(cls, resp, ns) -> List["ConnectionItem"]:
connection_item.server_address = connection_xml.get("serverAddress", None)
connection_item.server_port = connection_xml.get("serverPort", None)
connection_item.username = connection_xml.get("userName", None)
connection_item._query_tagging = string_to_bool(connection_xml.get("queryTaggingEnabled", None))
datasource_elem = connection_xml.find(".//t:datasource", namespaces=ns)
if datasource_elem is not None:
connection_item._datasource_id = datasource_elem.get("id", None)
Expand Down Expand Up @@ -93,4 +113,4 @@ def from_xml_element(cls, parsed_response, ns) -> List["ConnectionItem"]:

# Used to convert string represented boolean to a boolean type
def string_to_bool(s: str) -> bool:
return s.lower() == "true"
return s is not None and s.lower() == "true"
2 changes: 2 additions & 0 deletions tableauserverclient/server/request_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -1002,6 +1002,8 @@ def update_req(self, xml_request: ET.Element, connection_item: "ConnectionItem")
connection_element.attrib["password"] = connection_item.password
if connection_item.embed_password is not None:
connection_element.attrib["embedPassword"] = str(connection_item.embed_password).lower()
if connection_item.query_tagging is not None:
connection_element.attrib["queryTaggingEnabled"] = str(connection_item.query_tagging).lower()


class TaskRequest(object):
Expand Down
34 changes: 34 additions & 0 deletions test/test_connection_.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import unittest
import tableauserverclient as TSC


class DatasourceModelTests(unittest.TestCase):
def test_require_boolean_query_tag_fails(self):
conn = TSC.ConnectionItem()
conn._connection_type = "postgres"
with self.assertRaises(ValueError):
conn.query_tagging = "no"

def test_set_query_tag_normal_conn(self):
conn = TSC.ConnectionItem()
conn._connection_type = "postgres"
conn.query_tagging = True
self.assertEqual(conn.query_tagging, True)

def test_ignore_query_tag_for_hyper(self):
conn = TSC.ConnectionItem()
conn._connection_type = "hyper"
conn.query_tagging = True
self.assertEqual(conn.query_tagging, None)

def test_ignore_query_tag_for_teradata(self):
conn = TSC.ConnectionItem()
conn._connection_type = "teradata"
conn.query_tagging = True
self.assertEqual(conn.query_tagging, None)

def test_ignore_query_tag_for_snowflake(self):
conn = TSC.ConnectionItem()
conn._connection_type = "snowflake"
conn.query_tagging = True
self.assertEqual(conn.query_tagging, None)
11 changes: 10 additions & 1 deletion test/test_datasource_model.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import unittest

import tableauserverclient as TSC


Expand All @@ -9,3 +8,13 @@ def test_invalid_project_id(self):
datasource = TSC.DatasourceItem("10")
with self.assertRaises(ValueError):
datasource.project_id = None

def test_require_boolean_flag_bridge_fail(self):
datasource = TSC.DatasourceItem("10")
with self.assertRaises(ValueError):
datasource.use_remote_query_agent = "yes"

def test_require_boolean_flag_bridge_ok(self):
datasource = TSC.DatasourceItem("10")
datasource.use_remote_query_agent = True
self.assertEqual(datasource.use_remote_query_agent, True)
0