Repository: tableau/server-client-python

Issue:
This log line is overly chatty
https://github.com/tableau/server-client-python/blob/608aa7694d0560ea3c8c37b10127b11207e56e8d/tableauserverclient/server/endpoint/endpoint.py#L53

When using server client python to download workbooks or data sources and you've got log_level=Debug, this log line ends up blowing up your logs. It outputs the hexadecimal representation of the entire file you're downloading, which is not very helpful and explodes your log size. Can we remove this line, or only log out the response contents when you're not using the endpoint to download a file?

Comments:

Patch:
diff --git a/samples/download_view_image.py b/samples/download_view_image.py
index 2da2320..b95a862 100644
--- a/samples/download_view_image.py
+++ b/samples/download_view_image.py
@@ -43,7 +43,7 @@ def main():
     tableau_auth = TSC.TableauAuth(args.username, password, site_id=site_id)
     server = TSC.Server(args.server)
     # The new endpoint was introduced in Version 2.5
-    server.version = 2.5
+    server.version = "2.5"
 
     with server.auth.sign_in(tableau_auth):
         # Step 2: Query for the view that we want an image of
diff --git a/tableauserverclient/server/endpoint/endpoint.py b/tableauserverclient/server/endpoint/endpoint.py
index deaa94a..e78b2e0 100644
--- a/tableauserverclient/server/endpoint/endpoint.py
+++ b/tableauserverclient/server/endpoint/endpoint.py
@@ -27,6 +27,17 @@ class Endpoint(object):
 
         return headers
 
+    @staticmethod
+    def _safe_to_log(server_response):
+        '''Checks if the server_response content is not xml (eg binary image or zip)
+        and and replaces it with a constant
+        '''
+        ALLOWED_CONTENT_TYPES = ('application/xml',)
+        if server_response.headers.get('Content-Type', None) not in ALLOWED_CONTENT_TYPES:
+            return '[Truncated File Contents]'
+        else:
+            return server_response.content
+
     def _make_request(self, method, url, content=None, request_object=None,
                       auth_token=None, content_type=None, parameters=None):
         if request_object is not None:
@@ -50,7 +61,7 @@ class Endpoint(object):
         return server_response
 
     def _check_status(self, server_response):
-        logger.debug(server_response.content)
+        logger.debug(self._safe_to_log(server_response))
         if server_response.status_code not in Success_codes:
             raise ServerResponseError.from_response(server_response.content, self.parent_srv.namespace)
 


Test patch:
diff --git a/test/test_regression_tests.py b/test/test_regression_tests.py
index 95bdcea..8958c3c 100644
--- a/test/test_regression_tests.py
+++ b/test/test_regression_tests.py
@@ -1,8 +1,23 @@
 import unittest
 import tableauserverclient.server.request_factory as factory
+from tableauserverclient.server.endpoint import Endpoint
 
 
 class BugFix257(unittest.TestCase):
     def test_empty_request_works(self):
         result = factory.EmptyRequest().empty_req()
         self.assertEqual(b'<tsRequest />', result)
+
+
+class BugFix273(unittest.TestCase):
+    def test_binary_log_truncated(self):
+
+        class FakeResponse(object):
+
+            headers = {'Content-Type': 'application/octet-stream'}
+            content = b'\x1337' * 1000
+            status_code = 200
+
+        server_response = FakeResponse()
+
+        self.assertEqual(Endpoint._safe_to_log(server_response), '[Truncated File Contents]')