We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Databricks Data Source Broken
<!--

We use GitHub only for bug reports 🐛

Anything else should be posted to https://discuss.redash.io 👫

🚨For support, help & questions use https://discuss.redash.io/c/support
💡For feature requests & ideas use https://discuss.redash.io/c/feature-requests

**Found a security vulnerability?** Please email security@redash.io to report any security vulnerabilities. We will acknowledge receipt of your vulnerability and strive to send you regular updates about our progress. If you're curious about the status of your disclosure please feel free to email us again. If you want to encrypt your disclosure email, you can use this PGP key.

-->

### Issue Summary
Databricks data source does not work. The authorization token for Databricks data source needs to be converted into a byte string as it currently raises `TypeError: a bytes-like object is required, not 'str'`
Calling `.encode()` to transform to a byte string makes the data source work.

https://github.com/getredash/redash/blob/b089f5f0eff9b047c093dcc7abbd0ae5bfcf643c/redash/query_runner/databricks.py#L51-L52



### Steps to Reproduce

1. Create a Databricks data source
2. Run test connection and you will get the message: a bytes-like object is required, not 'str'

Any other info e.g. Why do you consider this to be a bug? What did you expect to happen instead?

### Technical details:

* Redash Version: master
* Browser/OS: Chrome
* How did you install Redash: Docker development environment


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `redash/query_runner/hive_ds.py`
Content:
```
1 import logging
2 import sys
3 import base64
4 
5 from redash.query_runner import *
6 from redash.utils import json_dumps
7 
8 logger = logging.getLogger(__name__)
9 
10 try:
11     from pyhive import hive
12     from pyhive.exc import DatabaseError
13     from thrift.transport import THttpClient
14 
15     enabled = True
16 except ImportError:
17     enabled = False
18 
19 COLUMN_NAME = 0
20 COLUMN_TYPE = 1
21 
22 types_map = {
23     "BIGINT_TYPE": TYPE_INTEGER,
24     "TINYINT_TYPE": TYPE_INTEGER,
25     "SMALLINT_TYPE": TYPE_INTEGER,
26     "INT_TYPE": TYPE_INTEGER,
27     "DOUBLE_TYPE": TYPE_FLOAT,
28     "DECIMAL_TYPE": TYPE_FLOAT,
29     "FLOAT_TYPE": TYPE_FLOAT,
30     "REAL_TYPE": TYPE_FLOAT,
31     "BOOLEAN_TYPE": TYPE_BOOLEAN,
32     "TIMESTAMP_TYPE": TYPE_DATETIME,
33     "DATE_TYPE": TYPE_DATE,
34     "CHAR_TYPE": TYPE_STRING,
35     "STRING_TYPE": TYPE_STRING,
36     "VARCHAR_TYPE": TYPE_STRING,
37 }
38 
39 
40 class Hive(BaseSQLQueryRunner):
41     should_annotate_query = False
42     noop_query = "SELECT 1"
43 
44     @classmethod
45     def configuration_schema(cls):
46         return {
47             "type": "object",
48             "properties": {
49                 "host": {"type": "string"},
50                 "port": {"type": "number"},
51                 "database": {"type": "string"},
52                 "username": {"type": "string"},
53             },
54             "order": ["host", "port", "database", "username"],
55             "required": ["host"],
56         }
57 
58     @classmethod
59     def type(cls):
60         return "hive"
61 
62     @classmethod
63     def enabled(cls):
64         return enabled
65 
66     def _get_tables(self, schema):
67         schemas_query = "show schemas"
68 
69         tables_query = "show tables in %s"
70 
71         columns_query = "show columns in %s.%s"
72 
73         for schema_name in [
74             a
75             for a in [
76                 str(a["database_name"]) for a in self._run_query_internal(schemas_query)
77             ]
78             if len(a) > 0
79         ]:
80             for table_name in [
81                 a
82                 for a in [
83                     str(a["tab_name"])
84                     for a in self._run_query_internal(tables_query % schema_name)
85                 ]
86                 if len(a) > 0
87             ]:
88                 columns = [
89                     a
90                     for a in [
91                         str(a["field"])
92                         for a in self._run_query_internal(
93                             columns_query % (schema_name, table_name)
94                         )
95                     ]
96                     if len(a) > 0
97                 ]
98 
99                 if schema_name != "default":
100                     table_name = "{}.{}".format(schema_name, table_name)
101 
102                 schema[table_name] = {"name": table_name, "columns": columns}
103         return list(schema.values())
104 
105     def _get_connection(self):
106         host = self.configuration["host"]
107 
108         connection = hive.connect(
109             host=host,
110             port=self.configuration.get("port", None),
111             database=self.configuration.get("database", "default"),
112             username=self.configuration.get("username", None),
113         )
114 
115         return connection
116 
117     def run_query(self, query, user):
118         connection = None
119         try:
120             connection = self._get_connection()
121             cursor = connection.cursor()
122 
123             cursor.execute(query)
124 
125             column_names = []
126             columns = []
127 
128             for column in cursor.description:
129                 column_name = column[COLUMN_NAME]
130                 column_names.append(column_name)
131 
132                 columns.append(
133                     {
134                         "name": column_name,
135                         "friendly_name": column_name,
136                         "type": types_map.get(column[COLUMN_TYPE], None),
137                     }
138                 )
139 
140             rows = [dict(zip(column_names, row)) for row in cursor]
141 
142             data = {"columns": columns, "rows": rows}
143             json_data = json_dumps(data)
144             error = None
145         except KeyboardInterrupt:
146             if connection:
147                 connection.cancel()
148             error = "Query cancelled by user."
149             json_data = None
150         except DatabaseError as e:
151             try:
152                 error = e.args[0].status.errorMessage
153             except AttributeError:
154                 error = str(e)
155             json_data = None
156         finally:
157             if connection:
158                 connection.close()
159 
160         return json_data, error
161 
162 
163 class HiveHttp(Hive):
164     @classmethod
165     def name(cls):
166         return "Hive (HTTP)"
167 
168     @classmethod
169     def type(cls):
170         return "hive_http"
171 
172     @classmethod
173     def configuration_schema(cls):
174         return {
175             "type": "object",
176             "properties": {
177                 "host": {"type": "string"},
178                 "port": {"type": "number"},
179                 "database": {"type": "string"},
180                 "username": {"type": "string"},
181                 "http_scheme": {
182                     "type": "string",
183                     "title": "HTTP Scheme (http or https)",
184                     "default": "https",
185                 },
186                 "http_path": {"type": "string", "title": "HTTP Path"},
187                 "http_password": {"type": "string", "title": "Password"},
188             },
189             "order": [
190                 "host",
191                 "port",
192                 "http_path",
193                 "username",
194                 "http_password",
195                 "database",
196                 "http_scheme",
197             ],
198             "secret": ["http_password"],
199             "required": ["host", "http_path"],
200         }
201 
202     def _get_connection(self):
203         host = self.configuration["host"]
204 
205         scheme = self.configuration.get("http_scheme", "https")
206 
207         # if path is set but is missing initial slash, append it
208         path = self.configuration.get("http_path", "")
209         if path and path[0] != "/":
210             path = "/" + path
211 
212         # if port is set prepend colon
213         port = self.configuration.get("port", "")
214         if port:
215             port = ":" + str(port)
216 
217         http_uri = "{}://{}{}{}".format(scheme, host, port, path)
218 
219         # create transport
220         transport = THttpClient.THttpClient(http_uri)
221 
222         # if username or password is set, add Authorization header
223         username = self.configuration.get("username", "")
224         password = self.configuration.get("http_password", "")
225         if username or password:
226             auth = base64.b64encode(username + ":" + password)
227             transport.setCustomHeaders({"Authorization": "Basic " + auth})
228 
229         # create connection
230         connection = hive.connect(thrift_transport=transport)
231 
232         return connection
233 
234 
235 register(Hive)
236 register(HiveHttp)
237
```

Path: `redash/query_runner/databricks.py`
Content:
```
1 import base64
2 from .hive_ds import Hive
3 from redash.query_runner import register
4 
5 try:
6     from pyhive import hive
7     from thrift.transport import THttpClient
8 
9     enabled = True
10 except ImportError:
11     enabled = False
12 
13 
14 class Databricks(Hive):
15     @classmethod
16     def type(cls):
17         return "databricks"
18 
19     @classmethod
20     def enabled(cls):
21         return enabled
22 
23     @classmethod
24     def configuration_schema(cls):
25         return {
26             "type": "object",
27             "properties": {
28                 "host": {"type": "string"},
29                 "database": {"type": "string"},
30                 "http_path": {"type": "string", "title": "HTTP Path"},
31                 "http_password": {"type": "string", "title": "Access Token"},
32             },
33             "order": ["host", "http_path", "http_password", "database"],
34             "secret": ["http_password"],
35             "required": ["host", "database", "http_path", "http_password"],
36         }
37 
38     def _get_connection(self):
39         host = self.configuration["host"]
40 
41         # if path is set but is missing initial slash, append it
42         path = self.configuration.get("http_path", "")
43         if path and path[0] != "/":
44             path = "/" + path
45 
46         http_uri = "https://{}{}".format(host, path)
47 
48         transport = THttpClient.THttpClient(http_uri)
49 
50         password = self.configuration.get("http_password", "")
51         auth = base64.b64encode("token:" + password)
52         transport.setCustomHeaders({"Authorization": "Basic " + auth})
53 
54         connection = hive.connect(thrift_transport=transport)
55         return connection
56 
57     def _get_tables(self, schema):
58         schemas_query = "show schemas"
59         tables_query = "show tables in %s"
60         columns_query = "show columns in %s.%s"
61 
62         schemas = self._run_query_internal(schemas_query)
63 
64         for schema_name in [
65             a for a in [str(a["databaseName"]) for a in schemas] if len(a) > 0
66         ]:
67             for table_name in [
68                 a
69                 for a in [
70                     str(a["tableName"])
71                     for a in self._run_query_internal(tables_query % schema_name)
72                 ]
73                 if len(a) > 0
74             ]:
75                 columns = [
76                     a
77                     for a in [
78                         str(a["col_name"])
79                         for a in self._run_query_internal(
80                             columns_query % (schema_name, table_name)
81                         )
82                     ]
83                     if len(a) > 0
84                 ]
85 
86                 if schema_name != "default":
87                     table_name = "{}.{}".format(schema_name, table_name)
88 
89                 schema[table_name] = {"name": table_name, "columns": columns}
90         return list(schema.values())
91 
92 
93 register(Databricks)
94
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/redash/query_runner/databricks.py b/redash/query_runner/databricks.py
--- a/redash/query_runner/databricks.py
+++ b/redash/query_runner/databricks.py
@@ -48,8 +48,8 @@
         transport = THttpClient.THttpClient(http_uri)
 
         password = self.configuration.get("http_password", "")
-        auth = base64.b64encode("token:" + password)
-        transport.setCustomHeaders({"Authorization": "Basic " + auth})
+        auth = base64.b64encode(b"token:" + password.encode("ascii"))
+        transport.setCustomHeaders({"Authorization": "Basic " + auth.decode()})
 
         connection = hive.connect(thrift_transport=transport)
         return connection
diff --git a/redash/query_runner/hive_ds.py b/redash/query_runner/hive_ds.py
--- a/redash/query_runner/hive_ds.py
+++ b/redash/query_runner/hive_ds.py
@@ -223,8 +223,8 @@
         username = self.configuration.get("username", "")
         password = self.configuration.get("http_password", "")
         if username or password:
-            auth = base64.b64encode(username + ":" + password)
-            transport.setCustomHeaders({"Authorization": "Basic " + auth})
+            auth = base64.b64encode(username.encode("ascii") + b":" + password.encode("ascii"))
+            transport.setCustomHeaders({"Authorization": "Basic " + auth.decode()})
 
         # create connection
         connection = hive.connect(thrift_transport=transport)

{"golden_diff": "diff --git a/redash/query_runner/databricks.py b/redash/query_runner/databricks.py\n--- a/redash/query_runner/databricks.py\n+++ b/redash/query_runner/databricks.py\n@@ -48,8 +48,8 @@\n         transport = THttpClient.THttpClient(http_uri)\n \n         password = self.configuration.get(\"http_password\", \"\")\n-        auth = base64.b64encode(\"token:\" + password)\n-        transport.setCustomHeaders({\"Authorization\": \"Basic \" + auth})\n+        auth = base64.b64encode(b\"token:\" + password.encode(\"ascii\"))\n+        transport.setCustomHeaders({\"Authorization\": \"Basic \" + auth.decode()})\n \n         connection = hive.connect(thrift_transport=transport)\n         return connection\ndiff --git a/redash/query_runner/hive_ds.py b/redash/query_runner/hive_ds.py\n--- a/redash/query_runner/hive_ds.py\n+++ b/redash/query_runner/hive_ds.py\n@@ -223,8 +223,8 @@\n         username = self.configuration.get(\"username\", \"\")\n         password = self.configuration.get(\"http_password\", \"\")\n         if username or password:\n-            auth = base64.b64encode(username + \":\" + password)\n-            transport.setCustomHeaders({\"Authorization\": \"Basic \" + auth})\n+            auth = base64.b64encode(username.encode(\"ascii\") + b\":\" + password.encode(\"ascii\"))\n+            transport.setCustomHeaders({\"Authorization\": \"Basic \" + auth.decode()})\n \n         # create connection\n         connection = hive.connect(thrift_transport=transport)\n", "issue": "Databricks Data Source Broken\n<!--\r\n\r\nWe use GitHub only for bug reports \ud83d\udc1b\r\n\r\nAnything else should be posted to https://discuss.redash.io \ud83d\udc6b\r\n\r\n\ud83d\udea8For support, help & questions use https://discuss.redash.io/c/support\r\n\ud83d\udca1For feature requests & ideas use https://discuss.redash.io/c/feature-requests\r\n\r\n**Found a security vulnerability?** Please email security@redash.io to report any security vulnerabilities. We will acknowledge receipt of your vulnerability and strive to send you regular updates about our progress. If you're curious about the status of your disclosure please feel free to email us again. If you want to encrypt your disclosure email, you can use this PGP key.\r\n\r\n-->\r\n\r\n### Issue Summary\r\nDatabricks data source does not work. The authorization token for Databricks data source needs to be converted into a byte string as it currently raises `TypeError: a bytes-like object is required, not 'str'`\r\nCalling `.encode()` to transform to a byte string makes the data source work.\r\n\r\nhttps://github.com/getredash/redash/blob/b089f5f0eff9b047c093dcc7abbd0ae5bfcf643c/redash/query_runner/databricks.py#L51-L52\r\n\r\n\r\n\r\n### Steps to Reproduce\r\n\r\n1. Create a Databricks data source\r\n2. Run test connection and you will get the message: a bytes-like object is required, not 'str'\r\n\r\nAny other info e.g. Why do you consider this to be a bug? What did you expect to happen instead?\r\n\r\n### Technical details:\r\n\r\n* Redash Version: master\r\n* Browser/OS: Chrome\r\n* How did you install Redash: Docker development environment\r\n\n", "before_files": [{"content": "import logging\nimport sys\nimport base64\n\nfrom redash.query_runner import *\nfrom redash.utils import json_dumps\n\nlogger = logging.getLogger(__name__)\n\ntry:\n    from pyhive import hive\n    from pyhive.exc import DatabaseError\n    from thrift.transport import THttpClient\n\n    enabled = True\nexcept ImportError:\n    enabled = False\n\nCOLUMN_NAME = 0\nCOLUMN_TYPE = 1\n\ntypes_map = {\n    \"BIGINT_TYPE\": TYPE_INTEGER,\n    \"TINYINT_TYPE\": TYPE_INTEGER,\n    \"SMALLINT_TYPE\": TYPE_INTEGER,\n    \"INT_TYPE\": TYPE_INTEGER,\n    \"DOUBLE_TYPE\": TYPE_FLOAT,\n    \"DECIMAL_TYPE\": TYPE_FLOAT,\n    \"FLOAT_TYPE\": TYPE_FLOAT,\n    \"REAL_TYPE\": TYPE_FLOAT,\n    \"BOOLEAN_TYPE\": TYPE_BOOLEAN,\n    \"TIMESTAMP_TYPE\": TYPE_DATETIME,\n    \"DATE_TYPE\": TYPE_DATE,\n    \"CHAR_TYPE\": TYPE_STRING,\n    \"STRING_TYPE\": TYPE_STRING,\n    \"VARCHAR_TYPE\": TYPE_STRING,\n}\n\n\nclass Hive(BaseSQLQueryRunner):\n    should_annotate_query = False\n    noop_query = \"SELECT 1\"\n\n    @classmethod\n    def configuration_schema(cls):\n        return {\n            \"type\": \"object\",\n            \"properties\": {\n                \"host\": {\"type\": \"string\"},\n                \"port\": {\"type\": \"number\"},\n                \"database\": {\"type\": \"string\"},\n                \"username\": {\"type\": \"string\"},\n            },\n            \"order\": [\"host\", \"port\", \"database\", \"username\"],\n            \"required\": [\"host\"],\n        }\n\n    @classmethod\n    def type(cls):\n        return \"hive\"\n\n    @classmethod\n    def enabled(cls):\n        return enabled\n\n    def _get_tables(self, schema):\n        schemas_query = \"show schemas\"\n\n        tables_query = \"show tables in %s\"\n\n        columns_query = \"show columns in %s.%s\"\n\n        for schema_name in [\n            a\n            for a in [\n                str(a[\"database_name\"]) for a in self._run_query_internal(schemas_query)\n            ]\n            if len(a) > 0\n        ]:\n            for table_name in [\n                a\n                for a in [\n                    str(a[\"tab_name\"])\n                    for a in self._run_query_internal(tables_query % schema_name)\n                ]\n                if len(a) > 0\n            ]:\n                columns = [\n                    a\n                    for a in [\n                        str(a[\"field\"])\n                        for a in self._run_query_internal(\n                            columns_query % (schema_name, table_name)\n                        )\n                    ]\n                    if len(a) > 0\n                ]\n\n                if schema_name != \"default\":\n                    table_name = \"{}.{}\".format(schema_name, table_name)\n\n                schema[table_name] = {\"name\": table_name, \"columns\": columns}\n        return list(schema.values())\n\n    def _get_connection(self):\n        host = self.configuration[\"host\"]\n\n        connection = hive.connect(\n            host=host,\n            port=self.configuration.get(\"port\", None),\n            database=self.configuration.get(\"database\", \"default\"),\n            username=self.configuration.get(\"username\", None),\n        )\n\n        return connection\n\n    def run_query(self, query, user):\n        connection = None\n        try:\n            connection = self._get_connection()\n            cursor = connection.cursor()\n\n            cursor.execute(query)\n\n            column_names = []\n            columns = []\n\n            for column in cursor.description:\n                column_name = column[COLUMN_NAME]\n                column_names.append(column_name)\n\n                columns.append(\n                    {\n                        \"name\": column_name,\n                        \"friendly_name\": column_name,\n                        \"type\": types_map.get(column[COLUMN_TYPE], None),\n                    }\n                )\n\n            rows = [dict(zip(column_names, row)) for row in cursor]\n\n            data = {\"columns\": columns, \"rows\": rows}\n            json_data = json_dumps(data)\n            error = None\n        except KeyboardInterrupt:\n            if connection:\n                connection.cancel()\n            error = \"Query cancelled by user.\"\n            json_data = None\n        except DatabaseError as e:\n            try:\n                error = e.args[0].status.errorMessage\n            except AttributeError:\n                error = str(e)\n            json_data = None\n        finally:\n            if connection:\n                connection.close()\n\n        return json_data, error\n\n\nclass HiveHttp(Hive):\n    @classmethod\n    def name(cls):\n        return \"Hive (HTTP)\"\n\n    @classmethod\n    def type(cls):\n        return \"hive_http\"\n\n    @classmethod\n    def configuration_schema(cls):\n        return {\n            \"type\": \"object\",\n            \"properties\": {\n                \"host\": {\"type\": \"string\"},\n                \"port\": {\"type\": \"number\"},\n                \"database\": {\"type\": \"string\"},\n                \"username\": {\"type\": \"string\"},\n                \"http_scheme\": {\n                    \"type\": \"string\",\n                    \"title\": \"HTTP Scheme (http or https)\",\n                    \"default\": \"https\",\n                },\n                \"http_path\": {\"type\": \"string\", \"title\": \"HTTP Path\"},\n                \"http_password\": {\"type\": \"string\", \"title\": \"Password\"},\n            },\n            \"order\": [\n                \"host\",\n                \"port\",\n                \"http_path\",\n                \"username\",\n                \"http_password\",\n                \"database\",\n                \"http_scheme\",\n            ],\n            \"secret\": [\"http_password\"],\n            \"required\": [\"host\", \"http_path\"],\n        }\n\n    def _get_connection(self):\n        host = self.configuration[\"host\"]\n\n        scheme = self.configuration.get(\"http_scheme\", \"https\")\n\n        # if path is set but is missing initial slash, append it\n        path = self.configuration.get(\"http_path\", \"\")\n        if path and path[0] != \"/\":\n            path = \"/\" + path\n\n        # if port is set prepend colon\n        port = self.configuration.get(\"port\", \"\")\n        if port:\n            port = \":\" + str(port)\n\n        http_uri = \"{}://{}{}{}\".format(scheme, host, port, path)\n\n        # create transport\n        transport = THttpClient.THttpClient(http_uri)\n\n        # if username or password is set, add Authorization header\n        username = self.configuration.get(\"username\", \"\")\n        password = self.configuration.get(\"http_password\", \"\")\n        if username or password:\n            auth = base64.b64encode(username + \":\" + password)\n            transport.setCustomHeaders({\"Authorization\": \"Basic \" + auth})\n\n        # create connection\n        connection = hive.connect(thrift_transport=transport)\n\n        return connection\n\n\nregister(Hive)\nregister(HiveHttp)\n", "path": "redash/query_runner/hive_ds.py"}, {"content": "import base64\nfrom .hive_ds import Hive\nfrom redash.query_runner import register\n\ntry:\n    from pyhive import hive\n    from thrift.transport import THttpClient\n\n    enabled = True\nexcept ImportError:\n    enabled = False\n\n\nclass Databricks(Hive):\n    @classmethod\n    def type(cls):\n        return \"databricks\"\n\n    @classmethod\n    def enabled(cls):\n        return enabled\n\n    @classmethod\n    def configuration_schema(cls):\n        return {\n            \"type\": \"object\",\n            \"properties\": {\n                \"host\": {\"type\": \"string\"},\n                \"database\": {\"type\": \"string\"},\n                \"http_path\": {\"type\": \"string\", \"title\": \"HTTP Path\"},\n                \"http_password\": {\"type\": \"string\", \"title\": \"Access Token\"},\n            },\n            \"order\": [\"host\", \"http_path\", \"http_password\", \"database\"],\n            \"secret\": [\"http_password\"],\n            \"required\": [\"host\", \"database\", \"http_path\", \"http_password\"],\n        }\n\n    def _get_connection(self):\n        host = self.configuration[\"host\"]\n\n        # if path is set but is missing initial slash, append it\n        path = self.configuration.get(\"http_path\", \"\")\n        if path and path[0] != \"/\":\n            path = \"/\" + path\n\n        http_uri = \"https://{}{}\".format(host, path)\n\n        transport = THttpClient.THttpClient(http_uri)\n\n        password = self.configuration.get(\"http_password\", \"\")\n        auth = base64.b64encode(\"token:\" + password)\n        transport.setCustomHeaders({\"Authorization\": \"Basic \" + auth})\n\n        connection = hive.connect(thrift_transport=transport)\n        return connection\n\n    def _get_tables(self, schema):\n        schemas_query = \"show schemas\"\n        tables_query = \"show tables in %s\"\n        columns_query = \"show columns in %s.%s\"\n\n        schemas = self._run_query_internal(schemas_query)\n\n        for schema_name in [\n            a for a in [str(a[\"databaseName\"]) for a in schemas] if len(a) > 0\n        ]:\n            for table_name in [\n                a\n                for a in [\n                    str(a[\"tableName\"])\n                    for a in self._run_query_internal(tables_query % schema_name)\n                ]\n                if len(a) > 0\n            ]:\n                columns = [\n                    a\n                    for a in [\n                        str(a[\"col_name\"])\n                        for a in self._run_query_internal(\n                            columns_query % (schema_name, table_name)\n                        )\n                    ]\n                    if len(a) > 0\n                ]\n\n                if schema_name != \"default\":\n                    table_name = \"{}.{}\".format(schema_name, table_name)\n\n                schema[table_name] = {\"name\": table_name, \"columns\": columns}\n        return list(schema.values())\n\n\nregister(Databricks)\n", "path": "redash/query_runner/databricks.py"}], "after_files": [{"content": "import logging\nimport sys\nimport base64\n\nfrom redash.query_runner import *\nfrom redash.utils import json_dumps\n\nlogger = logging.getLogger(__name__)\n\ntry:\n    from pyhive import hive\n    from pyhive.exc import DatabaseError\n    from thrift.transport import THttpClient\n\n    enabled = True\nexcept ImportError:\n    enabled = False\n\nCOLUMN_NAME = 0\nCOLUMN_TYPE = 1\n\ntypes_map = {\n    \"BIGINT_TYPE\": TYPE_INTEGER,\n    \"TINYINT_TYPE\": TYPE_INTEGER,\n    \"SMALLINT_TYPE\": TYPE_INTEGER,\n    \"INT_TYPE\": TYPE_INTEGER,\n    \"DOUBLE_TYPE\": TYPE_FLOAT,\n    \"DECIMAL_TYPE\": TYPE_FLOAT,\n    \"FLOAT_TYPE\": TYPE_FLOAT,\n    \"REAL_TYPE\": TYPE_FLOAT,\n    \"BOOLEAN_TYPE\": TYPE_BOOLEAN,\n    \"TIMESTAMP_TYPE\": TYPE_DATETIME,\n    \"DATE_TYPE\": TYPE_DATE,\n    \"CHAR_TYPE\": TYPE_STRING,\n    \"STRING_TYPE\": TYPE_STRING,\n    \"VARCHAR_TYPE\": TYPE_STRING,\n}\n\n\nclass Hive(BaseSQLQueryRunner):\n    should_annotate_query = False\n    noop_query = \"SELECT 1\"\n\n    @classmethod\n    def configuration_schema(cls):\n        return {\n            \"type\": \"object\",\n            \"properties\": {\n                \"host\": {\"type\": \"string\"},\n                \"port\": {\"type\": \"number\"},\n                \"database\": {\"type\": \"string\"},\n                \"username\": {\"type\": \"string\"},\n            },\n            \"order\": [\"host\", \"port\", \"database\", \"username\"],\n            \"required\": [\"host\"],\n        }\n\n    @classmethod\n    def type(cls):\n        return \"hive\"\n\n    @classmethod\n    def enabled(cls):\n        return enabled\n\n    def _get_tables(self, schema):\n        schemas_query = \"show schemas\"\n\n        tables_query = \"show tables in %s\"\n\n        columns_query = \"show columns in %s.%s\"\n\n        for schema_name in [\n            a\n            for a in [\n                str(a[\"database_name\"]) for a in self._run_query_internal(schemas_query)\n            ]\n            if len(a) > 0\n        ]:\n            for table_name in [\n                a\n                for a in [\n                    str(a[\"tab_name\"])\n                    for a in self._run_query_internal(tables_query % schema_name)\n                ]\n                if len(a) > 0\n            ]:\n                columns = [\n                    a\n                    for a in [\n                        str(a[\"field\"])\n                        for a in self._run_query_internal(\n                            columns_query % (schema_name, table_name)\n                        )\n                    ]\n                    if len(a) > 0\n                ]\n\n                if schema_name != \"default\":\n                    table_name = \"{}.{}\".format(schema_name, table_name)\n\n                schema[table_name] = {\"name\": table_name, \"columns\": columns}\n        return list(schema.values())\n\n    def _get_connection(self):\n        host = self.configuration[\"host\"]\n\n        connection = hive.connect(\n            host=host,\n            port=self.configuration.get(\"port\", None),\n            database=self.configuration.get(\"database\", \"default\"),\n            username=self.configuration.get(\"username\", None),\n        )\n\n        return connection\n\n    def run_query(self, query, user):\n        connection = None\n        try:\n            connection = self._get_connection()\n            cursor = connection.cursor()\n\n            cursor.execute(query)\n\n            column_names = []\n            columns = []\n\n            for column in cursor.description:\n                column_name = column[COLUMN_NAME]\n                column_names.append(column_name)\n\n                columns.append(\n                    {\n                        \"name\": column_name,\n                        \"friendly_name\": column_name,\n                        \"type\": types_map.get(column[COLUMN_TYPE], None),\n                    }\n                )\n\n            rows = [dict(zip(column_names, row)) for row in cursor]\n\n            data = {\"columns\": columns, \"rows\": rows}\n            json_data = json_dumps(data)\n            error = None\n        except KeyboardInterrupt:\n            if connection:\n                connection.cancel()\n            error = \"Query cancelled by user.\"\n            json_data = None\n        except DatabaseError as e:\n            try:\n                error = e.args[0].status.errorMessage\n            except AttributeError:\n                error = str(e)\n            json_data = None\n        finally:\n            if connection:\n                connection.close()\n\n        return json_data, error\n\n\nclass HiveHttp(Hive):\n    @classmethod\n    def name(cls):\n        return \"Hive (HTTP)\"\n\n    @classmethod\n    def type(cls):\n        return \"hive_http\"\n\n    @classmethod\n    def configuration_schema(cls):\n        return {\n            \"type\": \"object\",\n            \"properties\": {\n                \"host\": {\"type\": \"string\"},\n                \"port\": {\"type\": \"number\"},\n                \"database\": {\"type\": \"string\"},\n                \"username\": {\"type\": \"string\"},\n                \"http_scheme\": {\n                    \"type\": \"string\",\n                    \"title\": \"HTTP Scheme (http or https)\",\n                    \"default\": \"https\",\n                },\n                \"http_path\": {\"type\": \"string\", \"title\": \"HTTP Path\"},\n                \"http_password\": {\"type\": \"string\", \"title\": \"Password\"},\n            },\n            \"order\": [\n                \"host\",\n                \"port\",\n                \"http_path\",\n                \"username\",\n                \"http_password\",\n                \"database\",\n                \"http_scheme\",\n            ],\n            \"secret\": [\"http_password\"],\n            \"required\": [\"host\", \"http_path\"],\n        }\n\n    def _get_connection(self):\n        host = self.configuration[\"host\"]\n\n        scheme = self.configuration.get(\"http_scheme\", \"https\")\n\n        # if path is set but is missing initial slash, append it\n        path = self.configuration.get(\"http_path\", \"\")\n        if path and path[0] != \"/\":\n            path = \"/\" + path\n\n        # if port is set prepend colon\n        port = self.configuration.get(\"port\", \"\")\n        if port:\n            port = \":\" + str(port)\n\n        http_uri = \"{}://{}{}{}\".format(scheme, host, port, path)\n\n        # create transport\n        transport = THttpClient.THttpClient(http_uri)\n\n        # if username or password is set, add Authorization header\n        username = self.configuration.get(\"username\", \"\")\n        password = self.configuration.get(\"http_password\", \"\")\n        if username or password:\n            auth = base64.b64encode(username.encode(\"ascii\") + b\":\" + password.encode(\"ascii\"))\n            transport.setCustomHeaders({\"Authorization\": \"Basic \" + auth.decode()})\n\n        # create connection\n        connection = hive.connect(thrift_transport=transport)\n\n        return connection\n\n\nregister(Hive)\nregister(HiveHttp)\n", "path": "redash/query_runner/hive_ds.py"}, {"content": "import base64\nfrom .hive_ds import Hive\nfrom redash.query_runner import register\n\ntry:\n    from pyhive import hive\n    from thrift.transport import THttpClient\n\n    enabled = True\nexcept ImportError:\n    enabled = False\n\n\nclass Databricks(Hive):\n    @classmethod\n    def type(cls):\n        return \"databricks\"\n\n    @classmethod\n    def enabled(cls):\n        return enabled\n\n    @classmethod\n    def configuration_schema(cls):\n        return {\n            \"type\": \"object\",\n            \"properties\": {\n                \"host\": {\"type\": \"string\"},\n                \"database\": {\"type\": \"string\"},\n                \"http_path\": {\"type\": \"string\", \"title\": \"HTTP Path\"},\n                \"http_password\": {\"type\": \"string\", \"title\": \"Access Token\"},\n            },\n            \"order\": [\"host\", \"http_path\", \"http_password\", \"database\"],\n            \"secret\": [\"http_password\"],\n            \"required\": [\"host\", \"database\", \"http_path\", \"http_password\"],\n        }\n\n    def _get_connection(self):\n        host = self.configuration[\"host\"]\n\n        # if path is set but is missing initial slash, append it\n        path = self.configuration.get(\"http_path\", \"\")\n        if path and path[0] != \"/\":\n            path = \"/\" + path\n\n        http_uri = \"https://{}{}\".format(host, path)\n\n        transport = THttpClient.THttpClient(http_uri)\n\n        password = self.configuration.get(\"http_password\", \"\")\n        auth = base64.b64encode(b\"token:\" + password.encode(\"ascii\"))\n        transport.setCustomHeaders({\"Authorization\": \"Basic \" + auth.decode()})\n\n        connection = hive.connect(thrift_transport=transport)\n        return connection\n\n    def _get_tables(self, schema):\n        schemas_query = \"show schemas\"\n        tables_query = \"show tables in %s\"\n        columns_query = \"show columns in %s.%s\"\n\n        schemas = self._run_query_internal(schemas_query)\n\n        for schema_name in [\n            a for a in [str(a[\"databaseName\"]) for a in schemas] if len(a) > 0\n        ]:\n            for table_name in [\n                a\n                for a in [\n                    str(a[\"tableName\"])\n                    for a in self._run_query_internal(tables_query % schema_name)\n                ]\n                if len(a) > 0\n            ]:\n                columns = [\n                    a\n                    for a in [\n                        str(a[\"col_name\"])\n                        for a in self._run_query_internal(\n                            columns_query % (schema_name, table_name)\n                        )\n                    ]\n                    if len(a) > 0\n                ]\n\n                if schema_name != \"default\":\n                    table_name = \"{}.{}\".format(schema_name, table_name)\n\n                schema[table_name] = {\"name\": table_name, \"columns\": columns}\n        return list(schema.values())\n\n\nregister(Databricks)\n", "path": "redash/query_runner/databricks.py"}]}