mirror of
https://github.com/getredash/redash.git
synced 2025-12-19 17:37:19 -05:00
* Add support for Firebolt Database (#5606)
* Fixes issue #5622 (#5623)
* Update Readme to reflect Firebolt data source (#5649)
* Speed up BigQuery schema fetching (#5632)
New method improves schema fetching by as much as 98% on larger schemas
* Merge pull request from GHSA-vhc7-w7r8-8m34
* WIP: break the flask_oauthlib behavior
* Refactor google-oauth to use cryptographic state.
* Clean up comments
* Fix: tests didn't pass because of the scope issues.
Moved outside the create_blueprint method because this does not depend
on the Authlib object.
* Apply Arik's fixes. Tests pass.
* Merge pull request from GHSA-g8xr-f424-h2rv
* Merge pull request from GHSA-fcpv-hgq6-87h7
* Update changelog to incorporate security fixes and #5632 & #5606 (#5654)
* Update changelog to incorporate security fixes and #5632 & #5606
* Added reference to sqlite fix
* Bump to V10.1
* Missed package-lock.json on the first pass
* Add a REDASH_COOKIE_SECRET for circleci
* Revert "Add a REDASH_COOKIE_SECRET for circleci"
This reverts commit 45766364e8.
Moves config to the correct compose files
* Move advocate to core requirements.txt file
[debugging circleci failures]
Co-authored-by: rajeshSigmoid <89909168+rajeshSigmoid@users.noreply.github.com>
Co-authored-by: Aratrik Pal <44343120+AP2008@users.noreply.github.com>
Co-authored-by: rajeshmauryasde <rajeshk@sigmoidanalytics.com>
Co-authored-by: Katsuya Shimabukuro <katsu.generation.888@gmail.com>
98 lines
2.9 KiB
Python
98 lines
2.9 KiB
Python
import logging
|
|
import yaml
|
|
|
|
from redash.utils.requests_session import requests_or_advocate, UnacceptableAddressException
|
|
|
|
from redash.query_runner import *
|
|
from redash.utils import json_dumps
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
try:
|
|
import pandas as pd
|
|
import xlrd
|
|
import openpyxl
|
|
import numpy as np
|
|
enabled = True
|
|
except ImportError:
|
|
enabled = False
|
|
|
|
class Excel(BaseQueryRunner):
|
|
should_annotate_query = False
|
|
|
|
@classmethod
|
|
def enabled(cls):
|
|
return enabled
|
|
|
|
@classmethod
|
|
def configuration_schema(cls):
|
|
return {
|
|
'type': 'object',
|
|
'properties': {},
|
|
}
|
|
|
|
def __init__(self, configuration):
|
|
super(Excel, self).__init__(configuration)
|
|
self.syntax = "yaml"
|
|
|
|
def test_connection(self):
|
|
pass
|
|
|
|
def run_query(self, query, user):
|
|
path = ""
|
|
ua = ""
|
|
args = {}
|
|
try:
|
|
args = yaml.safe_load(query)
|
|
path = args['url']
|
|
args.pop('url', None)
|
|
ua = args['user-agent']
|
|
args.pop('user-agent', None)
|
|
|
|
except:
|
|
pass
|
|
|
|
try:
|
|
response = requests_or_advocate.get(url=path, headers={"User-agent": ua})
|
|
workbook = pd.read_excel(response.content, **args)
|
|
|
|
df = workbook.copy()
|
|
data = {'columns': [], 'rows': []}
|
|
conversions = [
|
|
{'pandas_type': np.integer, 'redash_type': 'integer',},
|
|
{'pandas_type': np.inexact, 'redash_type': 'float',},
|
|
{'pandas_type': np.datetime64, 'redash_type': 'datetime', 'to_redash': lambda x: x.strftime('%Y-%m-%d %H:%M:%S')},
|
|
{'pandas_type': np.bool_, 'redash_type': 'boolean'},
|
|
{'pandas_type': np.object, 'redash_type': 'string'}
|
|
]
|
|
labels = []
|
|
for dtype, label in zip(df.dtypes, df.columns):
|
|
for conversion in conversions:
|
|
if issubclass(dtype.type, conversion['pandas_type']):
|
|
data['columns'].append({'name': label, 'friendly_name': label, 'type': conversion['redash_type']})
|
|
labels.append(label)
|
|
func = conversion.get('to_redash')
|
|
if func:
|
|
df[label] = df[label].apply(func)
|
|
break
|
|
data['rows'] = df[labels].replace({np.nan: None}).to_dict(orient='records')
|
|
|
|
json_data = json_dumps(data)
|
|
error = None
|
|
except KeyboardInterrupt:
|
|
error = "Query cancelled by user."
|
|
json_data = None
|
|
except UnacceptableAddressException:
|
|
error = "Can't query private addresses."
|
|
json_data = None
|
|
except Exception as e:
|
|
error = "Error reading {0}. {1}".format(path, str(e))
|
|
json_data = None
|
|
|
|
return json_data, error
|
|
|
|
def get_schema(self):
|
|
raise NotSupported()
|
|
|
|
register(Excel)
|