We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Row count limitation when creating chart visualization
Graphing query with series data works fine when there are 1150 rows returned (total) but not when I go back further in time and get 1543 rows.  The chart shows just one of the two data points used as series.  The error in the console shows: "Highcharts error #12: www.highcharts.com/errors/12", and the link refers to the turboThreshold.  I did not see any references to this when searching through the code. 

Row count limitation when creating chart visualization
Graphing query with series data works fine when there are 1150 rows returned (total) but not when I go back further in time and get 1543 rows.  The chart shows just one of the two data points used as series.  The error in the console shows: "Highcharts error #12: www.highcharts.com/errors/12", and the link refers to the turboThreshold.  I did not see any references to this when searching through the code. 


--- 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/handlers/static.py`
Content:
```
1 import hashlib
2 import json
3 
4 from flask import render_template, send_from_directory, current_app
5 from flask_login import current_user, login_required
6 
7 from redash import settings
8 from redash.wsgi import app
9 
10 
11 @app.route('/admin/<anything>/<whatever>')
12 @app.route('/admin/<anything>')
13 @app.route('/dashboard/<anything>')
14 @app.route('/alerts')
15 @app.route('/alerts/<pk>')
16 @app.route('/queries')
17 @app.route('/data_sources')
18 @app.route('/data_sources/<pk>')
19 @app.route('/users')
20 @app.route('/users/<pk>')
21 @app.route('/queries/<query_id>')
22 @app.route('/queries/<query_id>/<anything>')
23 @app.route('/personal')
24 @app.route('/')
25 @login_required
26 def index(**kwargs):
27     email_md5 = hashlib.md5(current_user.email.lower()).hexdigest()
28     gravatar_url = "https://www.gravatar.com/avatar/%s?s=40" % email_md5
29 
30     user = {
31         'gravatar_url': gravatar_url,
32         'id': current_user.id,
33         'name': current_user.name,
34         'email': current_user.email,
35         'groups': current_user.groups,
36         'permissions': current_user.permissions
37     }
38 
39     features = {
40         'clientSideMetrics': settings.CLIENT_SIDE_METRICS,
41         'allowScriptsInUserInput': settings.ALLOW_SCRIPTS_IN_USER_INPUT
42     }
43 
44     return render_template("index.html", user=json.dumps(user), name=settings.NAME,
45                            features=json.dumps(features),
46                            analytics=settings.ANALYTICS)
47 
48 
49 @app.route('/<path:filename>')
50 def send_static(filename):
51     if current_app.debug:
52         cache_timeout = 0
53     else:
54         cache_timeout = None
55 
56     return send_from_directory(settings.STATIC_ASSETS_PATH, filename, cache_timeout=cache_timeout)
57
```

Path: `redash/settings.py`
Content:
```
1 import json
2 import os
3 import urlparse
4 from funcy import distinct
5 
6 
7 def parse_db_url(url):
8     url_parts = urlparse.urlparse(url)
9     connection = {'threadlocals': True}
10 
11     if url_parts.hostname and not url_parts.path:
12         connection['name'] = url_parts.hostname
13     else:
14         connection['name'] = url_parts.path[1:]
15         connection['host'] = url_parts.hostname
16         connection['port'] = url_parts.port
17         connection['user'] = url_parts.username
18         connection['password'] = url_parts.password
19 
20     return connection
21 
22 
23 def fix_assets_path(path):
24     fullpath = os.path.join(os.path.dirname(__file__), path)
25     return fullpath
26 
27 
28 def array_from_string(str):
29     array = str.split(',')
30     if "" in array:
31         array.remove("")
32 
33     return array
34 
35 
36 def set_from_string(str):
37     return set(array_from_string(str))
38 
39 
40 def parse_boolean(str):
41     return json.loads(str.lower())
42 
43 
44 def all_settings():
45     from types import ModuleType
46 
47     settings = {}
48     for name, item in globals().iteritems():
49         if not callable(item) and not name.startswith("__") and not isinstance(item, ModuleType):
50             settings[name] = item
51 
52     return settings
53 
54 
55 NAME = os.environ.get('REDASH_NAME', 're:dash')
56 
57 REDIS_URL = os.environ.get('REDASH_REDIS_URL', "redis://localhost:6379/0")
58 
59 STATSD_HOST = os.environ.get('REDASH_STATSD_HOST', "127.0.0.1")
60 STATSD_PORT = int(os.environ.get('REDASH_STATSD_PORT', "8125"))
61 STATSD_PREFIX = os.environ.get('REDASH_STATSD_PREFIX', "redash")
62 
63 # Connection settings for re:dash's own database (where we store the queries, results, etc)
64 DATABASE_CONFIG = parse_db_url(os.environ.get("REDASH_DATABASE_URL", "postgresql://postgres"))
65 
66 # Celery related settings
67 CELERY_BROKER = os.environ.get("REDASH_CELERY_BROKER", REDIS_URL)
68 CELERY_BACKEND = os.environ.get("REDASH_CELERY_BACKEND", CELERY_BROKER)
69 
70 # The following enables periodic job (every 5 minutes) of removing unused query results.
71 QUERY_RESULTS_CLEANUP_ENABLED = parse_boolean(os.environ.get("REDASH_QUERY_RESULTS_CLEANUP_ENABLED", "true"))
72 
73 AUTH_TYPE = os.environ.get("REDASH_AUTH_TYPE", "api_key")
74 PASSWORD_LOGIN_ENABLED = parse_boolean(os.environ.get("REDASH_PASSWORD_LOGIN_ENABLED", "true"))
75 
76 # Google Apps domain to allow access from; any user with email in this Google Apps will be allowed
77 # access
78 GOOGLE_APPS_DOMAIN = set_from_string(os.environ.get("REDASH_GOOGLE_APPS_DOMAIN", ""))
79 
80 GOOGLE_CLIENT_ID = os.environ.get("REDASH_GOOGLE_CLIENT_ID", "")
81 GOOGLE_CLIENT_SECRET = os.environ.get("REDASH_GOOGLE_CLIENT_SECRET", "")
82 GOOGLE_OAUTH_ENABLED = GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET
83 
84 SAML_METADATA_URL = os.environ.get("REDASH_SAML_METADATA_URL", "")
85 SAML_LOGIN_ENABLED = SAML_METADATA_URL != ""
86 SAML_CALLBACK_SERVER_NAME = os.environ.get("REDASH_SAML_CALLBACK_SERVER_NAME", "")
87 
88 STATIC_ASSETS_PATH = fix_assets_path(os.environ.get("REDASH_STATIC_ASSETS_PATH", "../rd_ui/app/"))
89 JOB_EXPIRY_TIME = int(os.environ.get("REDASH_JOB_EXPIRY_TIME", 3600 * 6))
90 COOKIE_SECRET = os.environ.get("REDASH_COOKIE_SECRET", "c292a0a3aa32397cdb050e233733900f")
91 LOG_LEVEL = os.environ.get("REDASH_LOG_LEVEL", "INFO")
92 ANALYTICS = os.environ.get("REDASH_ANALYTICS", "")
93 
94 # Mail settings:
95 MAIL_SERVER = os.environ.get('REDASH_MAIL_SERVER', 'localhost')
96 MAIL_PORT = int(os.environ.get('REDASH_MAIL_PORT', 25))
97 MAIL_USE_TLS = parse_boolean(os.environ.get('REDASH_MAIL_USE_TLS', 'false'))
98 MAIL_USE_SSL = parse_boolean(os.environ.get('REDASH_MAIL_USE_SSL', 'false'))
99 MAIL_USERNAME = os.environ.get('REDASH_MAIL_USERNAME', None)
100 MAIL_PASSWORD = os.environ.get('REDASH_MAIL_PASSWORD', None)
101 MAIL_DEFAULT_SENDER = os.environ.get('REDASH_MAIL_DEFAULT_SENDER', None)
102 MAIL_MAX_EMAILS = os.environ.get('REDASH_MAIL_MAX_EMAILS', None)
103 MAIL_ASCII_ATTACHMENTS = parse_boolean(os.environ.get('REDASH_MAIL_ASCII_ATTACHMENTS', 'false'))
104 
105 HOST = os.environ.get('REDASH_HOST', '')
106 
107 # CORS settings for the Query Result API (and possbily future external APIs).
108 # In most cases all you need to do is set REDASH_CORS_ACCESS_CONTROL_ALLOW_ORIGIN
109 # to the calling domain (or domains in a comma separated list).
110 ACCESS_CONTROL_ALLOW_ORIGIN = set_from_string(os.environ.get("REDASH_CORS_ACCESS_CONTROL_ALLOW_ORIGIN", ""))
111 ACCESS_CONTROL_ALLOW_CREDENTIALS = parse_boolean(os.environ.get("REDASH_CORS_ACCESS_CONTROL_ALLOW_CREDENTIALS", "false"))
112 ACCESS_CONTROL_REQUEST_METHOD = os.environ.get("REDASH_CORS_ACCESS_CONTROL_REQUEST_METHOD", "GET, POST, PUT")
113 ACCESS_CONTROL_ALLOW_HEADERS = os.environ.get("REDASH_CORS_ACCESS_CONTROL_ALLOW_HEADERS", "Content-Type")
114 
115 # Query Runners
116 default_query_runners = [
117     'redash.query_runner.big_query',
118     'redash.query_runner.google_spreadsheets',
119     'redash.query_runner.graphite',
120     'redash.query_runner.mongodb',
121     'redash.query_runner.mysql',
122     'redash.query_runner.pg',
123     'redash.query_runner.url',
124     'redash.query_runner.influx_db',
125     'redash.query_runner.elasticsearch',
126     'redash.query_runner.presto',
127     'redash.query_runner.hive_ds',
128     'redash.query_runner.impala_ds',
129     'redash.query_runner.vertica',
130     'redash.query_runner.treasuredata'
131 ]
132 
133 enabled_query_runners = array_from_string(os.environ.get("REDASH_ENABLED_QUERY_RUNNERS", ",".join(default_query_runners)))
134 additional_query_runners = array_from_string(os.environ.get("REDASH_ADDITIONAL_QUERY_RUNNERS", ""))
135 
136 QUERY_RUNNERS = distinct(enabled_query_runners + additional_query_runners)
137 
138 # Support for Sentry (http://getsentry.com/). Just set your Sentry DSN to enable it:
139 SENTRY_DSN = os.environ.get("REDASH_SENTRY_DSN", "")
140 
141 # Client side toggles:
142 ALLOW_SCRIPTS_IN_USER_INPUT = parse_boolean(os.environ.get("REDASH_ALLOW_SCRIPTS_IN_USER_INPUT", "false"))
143 CLIENT_SIDE_METRICS = parse_boolean(os.environ.get("REDASH_CLIENT_SIDE_METRICS", "false"))
144 
145 # Features:
146 FEATURE_ALLOW_ALL_TO_EDIT_QUERIES = parse_boolean(os.environ.get("REDASH_FEATURE_ALLOW_ALL_TO_EDIT", "true"))
147 FEATURE_TABLES_PERMISSIONS = parse_boolean(os.environ.get("REDASH_FEATURE_TABLES_PERMISSIONS", "false"))
148 
149 # BigQuery
150 BIGQUERY_HTTP_TIMEOUT = int(os.environ.get("REDASH_BIGQUERY_HTTP_TIMEOUT", "600"))
151
```
--- 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/handlers/static.py b/redash/handlers/static.py
--- a/redash/handlers/static.py
+++ b/redash/handlers/static.py
@@ -38,7 +38,8 @@
 
     features = {
         'clientSideMetrics': settings.CLIENT_SIDE_METRICS,
-        'allowScriptsInUserInput': settings.ALLOW_SCRIPTS_IN_USER_INPUT
+        'allowScriptsInUserInput': settings.ALLOW_SCRIPTS_IN_USER_INPUT,
+        'highChartsTurboThreshold': settings.HIGHCHARTS_TURBO_THRESHOLD
     }
 
     return render_template("index.html", user=json.dumps(user), name=settings.NAME,
diff --git a/redash/settings.py b/redash/settings.py
--- a/redash/settings.py
+++ b/redash/settings.py
@@ -142,6 +142,8 @@
 # Client side toggles:
 ALLOW_SCRIPTS_IN_USER_INPUT = parse_boolean(os.environ.get("REDASH_ALLOW_SCRIPTS_IN_USER_INPUT", "false"))
 CLIENT_SIDE_METRICS = parse_boolean(os.environ.get("REDASH_CLIENT_SIDE_METRICS", "false"))
+# http://api.highcharts.com/highcharts#plotOptions.series.turboThreshold
+HIGHCHARTS_TURBO_THRESHOLD = int(os.environ.get("REDASH_HIGHCHARTS_TURBO_THRESHOLD", "1000"))
 
 # Features:
 FEATURE_ALLOW_ALL_TO_EDIT_QUERIES = parse_boolean(os.environ.get("REDASH_FEATURE_ALLOW_ALL_TO_EDIT", "true"))

{"golden_diff": "diff --git a/redash/handlers/static.py b/redash/handlers/static.py\n--- a/redash/handlers/static.py\n+++ b/redash/handlers/static.py\n@@ -38,7 +38,8 @@\n \n     features = {\n         'clientSideMetrics': settings.CLIENT_SIDE_METRICS,\n-        'allowScriptsInUserInput': settings.ALLOW_SCRIPTS_IN_USER_INPUT\n+        'allowScriptsInUserInput': settings.ALLOW_SCRIPTS_IN_USER_INPUT,\n+        'highChartsTurboThreshold': settings.HIGHCHARTS_TURBO_THRESHOLD\n     }\n \n     return render_template(\"index.html\", user=json.dumps(user), name=settings.NAME,\ndiff --git a/redash/settings.py b/redash/settings.py\n--- a/redash/settings.py\n+++ b/redash/settings.py\n@@ -142,6 +142,8 @@\n # Client side toggles:\n ALLOW_SCRIPTS_IN_USER_INPUT = parse_boolean(os.environ.get(\"REDASH_ALLOW_SCRIPTS_IN_USER_INPUT\", \"false\"))\n CLIENT_SIDE_METRICS = parse_boolean(os.environ.get(\"REDASH_CLIENT_SIDE_METRICS\", \"false\"))\n+# http://api.highcharts.com/highcharts#plotOptions.series.turboThreshold\n+HIGHCHARTS_TURBO_THRESHOLD = int(os.environ.get(\"REDASH_HIGHCHARTS_TURBO_THRESHOLD\", \"1000\"))\n \n # Features:\n FEATURE_ALLOW_ALL_TO_EDIT_QUERIES = parse_boolean(os.environ.get(\"REDASH_FEATURE_ALLOW_ALL_TO_EDIT\", \"true\"))\n", "issue": "Row count limitation when creating chart visualization\nGraphing query with series data works fine when there are 1150 rows returned (total) but not when I go back further in time and get 1543 rows.  The chart shows just one of the two data points used as series.  The error in the console shows: \"Highcharts error #12: www.highcharts.com/errors/12\", and the link refers to the turboThreshold.  I did not see any references to this when searching through the code. \n\nRow count limitation when creating chart visualization\nGraphing query with series data works fine when there are 1150 rows returned (total) but not when I go back further in time and get 1543 rows.  The chart shows just one of the two data points used as series.  The error in the console shows: \"Highcharts error #12: www.highcharts.com/errors/12\", and the link refers to the turboThreshold.  I did not see any references to this when searching through the code. \n\n", "before_files": [{"content": "import hashlib\nimport json\n\nfrom flask import render_template, send_from_directory, current_app\nfrom flask_login import current_user, login_required\n\nfrom redash import settings\nfrom redash.wsgi import app\n\n\n@app.route('/admin/<anything>/<whatever>')\n@app.route('/admin/<anything>')\n@app.route('/dashboard/<anything>')\n@app.route('/alerts')\n@app.route('/alerts/<pk>')\n@app.route('/queries')\n@app.route('/data_sources')\n@app.route('/data_sources/<pk>')\n@app.route('/users')\n@app.route('/users/<pk>')\n@app.route('/queries/<query_id>')\n@app.route('/queries/<query_id>/<anything>')\n@app.route('/personal')\n@app.route('/')\n@login_required\ndef index(**kwargs):\n    email_md5 = hashlib.md5(current_user.email.lower()).hexdigest()\n    gravatar_url = \"https://www.gravatar.com/avatar/%s?s=40\" % email_md5\n\n    user = {\n        'gravatar_url': gravatar_url,\n        'id': current_user.id,\n        'name': current_user.name,\n        'email': current_user.email,\n        'groups': current_user.groups,\n        'permissions': current_user.permissions\n    }\n\n    features = {\n        'clientSideMetrics': settings.CLIENT_SIDE_METRICS,\n        'allowScriptsInUserInput': settings.ALLOW_SCRIPTS_IN_USER_INPUT\n    }\n\n    return render_template(\"index.html\", user=json.dumps(user), name=settings.NAME,\n                           features=json.dumps(features),\n                           analytics=settings.ANALYTICS)\n\n\n@app.route('/<path:filename>')\ndef send_static(filename):\n    if current_app.debug:\n        cache_timeout = 0\n    else:\n        cache_timeout = None\n\n    return send_from_directory(settings.STATIC_ASSETS_PATH, filename, cache_timeout=cache_timeout)\n", "path": "redash/handlers/static.py"}, {"content": "import json\nimport os\nimport urlparse\nfrom funcy import distinct\n\n\ndef parse_db_url(url):\n    url_parts = urlparse.urlparse(url)\n    connection = {'threadlocals': True}\n\n    if url_parts.hostname and not url_parts.path:\n        connection['name'] = url_parts.hostname\n    else:\n        connection['name'] = url_parts.path[1:]\n        connection['host'] = url_parts.hostname\n        connection['port'] = url_parts.port\n        connection['user'] = url_parts.username\n        connection['password'] = url_parts.password\n\n    return connection\n\n\ndef fix_assets_path(path):\n    fullpath = os.path.join(os.path.dirname(__file__), path)\n    return fullpath\n\n\ndef array_from_string(str):\n    array = str.split(',')\n    if \"\" in array:\n        array.remove(\"\")\n\n    return array\n\n\ndef set_from_string(str):\n    return set(array_from_string(str))\n\n\ndef parse_boolean(str):\n    return json.loads(str.lower())\n\n\ndef all_settings():\n    from types import ModuleType\n\n    settings = {}\n    for name, item in globals().iteritems():\n        if not callable(item) and not name.startswith(\"__\") and not isinstance(item, ModuleType):\n            settings[name] = item\n\n    return settings\n\n\nNAME = os.environ.get('REDASH_NAME', 're:dash')\n\nREDIS_URL = os.environ.get('REDASH_REDIS_URL', \"redis://localhost:6379/0\")\n\nSTATSD_HOST = os.environ.get('REDASH_STATSD_HOST', \"127.0.0.1\")\nSTATSD_PORT = int(os.environ.get('REDASH_STATSD_PORT', \"8125\"))\nSTATSD_PREFIX = os.environ.get('REDASH_STATSD_PREFIX', \"redash\")\n\n# Connection settings for re:dash's own database (where we store the queries, results, etc)\nDATABASE_CONFIG = parse_db_url(os.environ.get(\"REDASH_DATABASE_URL\", \"postgresql://postgres\"))\n\n# Celery related settings\nCELERY_BROKER = os.environ.get(\"REDASH_CELERY_BROKER\", REDIS_URL)\nCELERY_BACKEND = os.environ.get(\"REDASH_CELERY_BACKEND\", CELERY_BROKER)\n\n# The following enables periodic job (every 5 minutes) of removing unused query results.\nQUERY_RESULTS_CLEANUP_ENABLED = parse_boolean(os.environ.get(\"REDASH_QUERY_RESULTS_CLEANUP_ENABLED\", \"true\"))\n\nAUTH_TYPE = os.environ.get(\"REDASH_AUTH_TYPE\", \"api_key\")\nPASSWORD_LOGIN_ENABLED = parse_boolean(os.environ.get(\"REDASH_PASSWORD_LOGIN_ENABLED\", \"true\"))\n\n# Google Apps domain to allow access from; any user with email in this Google Apps will be allowed\n# access\nGOOGLE_APPS_DOMAIN = set_from_string(os.environ.get(\"REDASH_GOOGLE_APPS_DOMAIN\", \"\"))\n\nGOOGLE_CLIENT_ID = os.environ.get(\"REDASH_GOOGLE_CLIENT_ID\", \"\")\nGOOGLE_CLIENT_SECRET = os.environ.get(\"REDASH_GOOGLE_CLIENT_SECRET\", \"\")\nGOOGLE_OAUTH_ENABLED = GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET\n\nSAML_METADATA_URL = os.environ.get(\"REDASH_SAML_METADATA_URL\", \"\")\nSAML_LOGIN_ENABLED = SAML_METADATA_URL != \"\"\nSAML_CALLBACK_SERVER_NAME = os.environ.get(\"REDASH_SAML_CALLBACK_SERVER_NAME\", \"\")\n\nSTATIC_ASSETS_PATH = fix_assets_path(os.environ.get(\"REDASH_STATIC_ASSETS_PATH\", \"../rd_ui/app/\"))\nJOB_EXPIRY_TIME = int(os.environ.get(\"REDASH_JOB_EXPIRY_TIME\", 3600 * 6))\nCOOKIE_SECRET = os.environ.get(\"REDASH_COOKIE_SECRET\", \"c292a0a3aa32397cdb050e233733900f\")\nLOG_LEVEL = os.environ.get(\"REDASH_LOG_LEVEL\", \"INFO\")\nANALYTICS = os.environ.get(\"REDASH_ANALYTICS\", \"\")\n\n# Mail settings:\nMAIL_SERVER = os.environ.get('REDASH_MAIL_SERVER', 'localhost')\nMAIL_PORT = int(os.environ.get('REDASH_MAIL_PORT', 25))\nMAIL_USE_TLS = parse_boolean(os.environ.get('REDASH_MAIL_USE_TLS', 'false'))\nMAIL_USE_SSL = parse_boolean(os.environ.get('REDASH_MAIL_USE_SSL', 'false'))\nMAIL_USERNAME = os.environ.get('REDASH_MAIL_USERNAME', None)\nMAIL_PASSWORD = os.environ.get('REDASH_MAIL_PASSWORD', None)\nMAIL_DEFAULT_SENDER = os.environ.get('REDASH_MAIL_DEFAULT_SENDER', None)\nMAIL_MAX_EMAILS = os.environ.get('REDASH_MAIL_MAX_EMAILS', None)\nMAIL_ASCII_ATTACHMENTS = parse_boolean(os.environ.get('REDASH_MAIL_ASCII_ATTACHMENTS', 'false'))\n\nHOST = os.environ.get('REDASH_HOST', '')\n\n# CORS settings for the Query Result API (and possbily future external APIs).\n# In most cases all you need to do is set REDASH_CORS_ACCESS_CONTROL_ALLOW_ORIGIN\n# to the calling domain (or domains in a comma separated list).\nACCESS_CONTROL_ALLOW_ORIGIN = set_from_string(os.environ.get(\"REDASH_CORS_ACCESS_CONTROL_ALLOW_ORIGIN\", \"\"))\nACCESS_CONTROL_ALLOW_CREDENTIALS = parse_boolean(os.environ.get(\"REDASH_CORS_ACCESS_CONTROL_ALLOW_CREDENTIALS\", \"false\"))\nACCESS_CONTROL_REQUEST_METHOD = os.environ.get(\"REDASH_CORS_ACCESS_CONTROL_REQUEST_METHOD\", \"GET, POST, PUT\")\nACCESS_CONTROL_ALLOW_HEADERS = os.environ.get(\"REDASH_CORS_ACCESS_CONTROL_ALLOW_HEADERS\", \"Content-Type\")\n\n# Query Runners\ndefault_query_runners = [\n    'redash.query_runner.big_query',\n    'redash.query_runner.google_spreadsheets',\n    'redash.query_runner.graphite',\n    'redash.query_runner.mongodb',\n    'redash.query_runner.mysql',\n    'redash.query_runner.pg',\n    'redash.query_runner.url',\n    'redash.query_runner.influx_db',\n    'redash.query_runner.elasticsearch',\n    'redash.query_runner.presto',\n    'redash.query_runner.hive_ds',\n    'redash.query_runner.impala_ds',\n    'redash.query_runner.vertica',\n    'redash.query_runner.treasuredata'\n]\n\nenabled_query_runners = array_from_string(os.environ.get(\"REDASH_ENABLED_QUERY_RUNNERS\", \",\".join(default_query_runners)))\nadditional_query_runners = array_from_string(os.environ.get(\"REDASH_ADDITIONAL_QUERY_RUNNERS\", \"\"))\n\nQUERY_RUNNERS = distinct(enabled_query_runners + additional_query_runners)\n\n# Support for Sentry (http://getsentry.com/). Just set your Sentry DSN to enable it:\nSENTRY_DSN = os.environ.get(\"REDASH_SENTRY_DSN\", \"\")\n\n# Client side toggles:\nALLOW_SCRIPTS_IN_USER_INPUT = parse_boolean(os.environ.get(\"REDASH_ALLOW_SCRIPTS_IN_USER_INPUT\", \"false\"))\nCLIENT_SIDE_METRICS = parse_boolean(os.environ.get(\"REDASH_CLIENT_SIDE_METRICS\", \"false\"))\n\n# Features:\nFEATURE_ALLOW_ALL_TO_EDIT_QUERIES = parse_boolean(os.environ.get(\"REDASH_FEATURE_ALLOW_ALL_TO_EDIT\", \"true\"))\nFEATURE_TABLES_PERMISSIONS = parse_boolean(os.environ.get(\"REDASH_FEATURE_TABLES_PERMISSIONS\", \"false\"))\n\n# BigQuery\nBIGQUERY_HTTP_TIMEOUT = int(os.environ.get(\"REDASH_BIGQUERY_HTTP_TIMEOUT\", \"600\"))\n", "path": "redash/settings.py"}], "after_files": [{"content": "import hashlib\nimport json\n\nfrom flask import render_template, send_from_directory, current_app\nfrom flask_login import current_user, login_required\n\nfrom redash import settings\nfrom redash.wsgi import app\n\n\n@app.route('/admin/<anything>/<whatever>')\n@app.route('/admin/<anything>')\n@app.route('/dashboard/<anything>')\n@app.route('/alerts')\n@app.route('/alerts/<pk>')\n@app.route('/queries')\n@app.route('/data_sources')\n@app.route('/data_sources/<pk>')\n@app.route('/users')\n@app.route('/users/<pk>')\n@app.route('/queries/<query_id>')\n@app.route('/queries/<query_id>/<anything>')\n@app.route('/personal')\n@app.route('/')\n@login_required\ndef index(**kwargs):\n    email_md5 = hashlib.md5(current_user.email.lower()).hexdigest()\n    gravatar_url = \"https://www.gravatar.com/avatar/%s?s=40\" % email_md5\n\n    user = {\n        'gravatar_url': gravatar_url,\n        'id': current_user.id,\n        'name': current_user.name,\n        'email': current_user.email,\n        'groups': current_user.groups,\n        'permissions': current_user.permissions\n    }\n\n    features = {\n        'clientSideMetrics': settings.CLIENT_SIDE_METRICS,\n        'allowScriptsInUserInput': settings.ALLOW_SCRIPTS_IN_USER_INPUT,\n        'highChartsTurboThreshold': settings.HIGHCHARTS_TURBO_THRESHOLD\n    }\n\n    return render_template(\"index.html\", user=json.dumps(user), name=settings.NAME,\n                           features=json.dumps(features),\n                           analytics=settings.ANALYTICS)\n\n\n@app.route('/<path:filename>')\ndef send_static(filename):\n    if current_app.debug:\n        cache_timeout = 0\n    else:\n        cache_timeout = None\n\n    return send_from_directory(settings.STATIC_ASSETS_PATH, filename, cache_timeout=cache_timeout)\n", "path": "redash/handlers/static.py"}, {"content": "import json\nimport os\nimport urlparse\nfrom funcy import distinct\n\n\ndef parse_db_url(url):\n    url_parts = urlparse.urlparse(url)\n    connection = {'threadlocals': True}\n\n    if url_parts.hostname and not url_parts.path:\n        connection['name'] = url_parts.hostname\n    else:\n        connection['name'] = url_parts.path[1:]\n        connection['host'] = url_parts.hostname\n        connection['port'] = url_parts.port\n        connection['user'] = url_parts.username\n        connection['password'] = url_parts.password\n\n    return connection\n\n\ndef fix_assets_path(path):\n    fullpath = os.path.join(os.path.dirname(__file__), path)\n    return fullpath\n\n\ndef array_from_string(str):\n    array = str.split(',')\n    if \"\" in array:\n        array.remove(\"\")\n\n    return array\n\n\ndef set_from_string(str):\n    return set(array_from_string(str))\n\n\ndef parse_boolean(str):\n    return json.loads(str.lower())\n\n\ndef all_settings():\n    from types import ModuleType\n\n    settings = {}\n    for name, item in globals().iteritems():\n        if not callable(item) and not name.startswith(\"__\") and not isinstance(item, ModuleType):\n            settings[name] = item\n\n    return settings\n\n\nNAME = os.environ.get('REDASH_NAME', 're:dash')\n\nREDIS_URL = os.environ.get('REDASH_REDIS_URL', \"redis://localhost:6379/0\")\n\nSTATSD_HOST = os.environ.get('REDASH_STATSD_HOST', \"127.0.0.1\")\nSTATSD_PORT = int(os.environ.get('REDASH_STATSD_PORT', \"8125\"))\nSTATSD_PREFIX = os.environ.get('REDASH_STATSD_PREFIX', \"redash\")\n\n# Connection settings for re:dash's own database (where we store the queries, results, etc)\nDATABASE_CONFIG = parse_db_url(os.environ.get(\"REDASH_DATABASE_URL\", \"postgresql://postgres\"))\n\n# Celery related settings\nCELERY_BROKER = os.environ.get(\"REDASH_CELERY_BROKER\", REDIS_URL)\nCELERY_BACKEND = os.environ.get(\"REDASH_CELERY_BACKEND\", CELERY_BROKER)\n\n# The following enables periodic job (every 5 minutes) of removing unused query results. Behind this \"feature flag\" until\n# proved to be \"safe\".\nQUERY_RESULTS_CLEANUP_ENABLED = parse_boolean(os.environ.get(\"REDASH_QUERY_RESULTS_CLEANUP_ENABLED\", \"true\"))\n\nAUTH_TYPE = os.environ.get(\"REDASH_AUTH_TYPE\", \"api_key\")\nPASSWORD_LOGIN_ENABLED = parse_boolean(os.environ.get(\"REDASH_PASSWORD_LOGIN_ENABLED\", \"true\"))\n\n# Google Apps domain to allow access from; any user with email in this Google Apps will be allowed\n# access\nGOOGLE_APPS_DOMAIN = set_from_string(os.environ.get(\"REDASH_GOOGLE_APPS_DOMAIN\", \"\"))\n\nGOOGLE_CLIENT_ID = os.environ.get(\"REDASH_GOOGLE_CLIENT_ID\", \"\")\nGOOGLE_CLIENT_SECRET = os.environ.get(\"REDASH_GOOGLE_CLIENT_SECRET\", \"\")\nGOOGLE_OAUTH_ENABLED = GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET\n\nSAML_METADATA_URL = os.environ.get(\"REDASH_SAML_METADATA_URL\", \"\")\nSAML_LOGIN_ENABLED = SAML_METADATA_URL != \"\"\nSAML_CALLBACK_SERVER_NAME = os.environ.get(\"REDASH_SAML_CALLBACK_SERVER_NAME\", \"\")\n\nSTATIC_ASSETS_PATH = fix_assets_path(os.environ.get(\"REDASH_STATIC_ASSETS_PATH\", \"../rd_ui/app/\"))\nJOB_EXPIRY_TIME = int(os.environ.get(\"REDASH_JOB_EXPIRY_TIME\", 3600 * 6))\nCOOKIE_SECRET = os.environ.get(\"REDASH_COOKIE_SECRET\", \"c292a0a3aa32397cdb050e233733900f\")\nLOG_LEVEL = os.environ.get(\"REDASH_LOG_LEVEL\", \"INFO\")\nANALYTICS = os.environ.get(\"REDASH_ANALYTICS\", \"\")\n\n# Mail settings:\nMAIL_SERVER = os.environ.get('REDASH_MAIL_SERVER', 'localhost')\nMAIL_PORT = int(os.environ.get('REDASH_MAIL_PORT', 25))\nMAIL_USE_TLS = parse_boolean(os.environ.get('REDASH_MAIL_USE_TLS', 'false'))\nMAIL_USE_SSL = parse_boolean(os.environ.get('REDASH_MAIL_USE_SSL', 'false'))\nMAIL_USERNAME = os.environ.get('REDASH_MAIL_USERNAME', None)\nMAIL_PASSWORD = os.environ.get('REDASH_MAIL_PASSWORD', None)\nMAIL_DEFAULT_SENDER = os.environ.get('REDASH_MAIL_DEFAULT_SENDER', None)\nMAIL_MAX_EMAILS = os.environ.get('REDASH_MAIL_MAX_EMAILS', None)\nMAIL_ASCII_ATTACHMENTS = parse_boolean(os.environ.get('REDASH_MAIL_ASCII_ATTACHMENTS', 'false'))\n\nHOST = os.environ.get('REDASH_HOST', '')\n\n# CORS settings for the Query Result API (and possbily future external APIs).\n# In most cases all you need to do is set REDASH_CORS_ACCESS_CONTROL_ALLOW_ORIGIN\n# to the calling domain (or domains in a comma separated list).\nACCESS_CONTROL_ALLOW_ORIGIN = set_from_string(os.environ.get(\"REDASH_CORS_ACCESS_CONTROL_ALLOW_ORIGIN\", \"\"))\nACCESS_CONTROL_ALLOW_CREDENTIALS = parse_boolean(os.environ.get(\"REDASH_CORS_ACCESS_CONTROL_ALLOW_CREDENTIALS\", \"false\"))\nACCESS_CONTROL_REQUEST_METHOD = os.environ.get(\"REDASH_CORS_ACCESS_CONTROL_REQUEST_METHOD\", \"GET, POST, PUT\")\nACCESS_CONTROL_ALLOW_HEADERS = os.environ.get(\"REDASH_CORS_ACCESS_CONTROL_ALLOW_HEADERS\", \"Content-Type\")\n\n# Query Runners\ndefault_query_runners = [\n    'redash.query_runner.big_query',\n    'redash.query_runner.google_spreadsheets',\n    'redash.query_runner.graphite',\n    'redash.query_runner.mongodb',\n    'redash.query_runner.mysql',\n    'redash.query_runner.pg',\n    'redash.query_runner.url',\n    'redash.query_runner.influx_db',\n    'redash.query_runner.elasticsearch',\n    'redash.query_runner.presto',\n    'redash.query_runner.hive_ds',\n    'redash.query_runner.impala_ds',\n    'redash.query_runner.vertica',\n    'redash.query_runner.treasuredata'\n]\n\nenabled_query_runners = array_from_string(os.environ.get(\"REDASH_ENABLED_QUERY_RUNNERS\", \",\".join(default_query_runners)))\nadditional_query_runners = array_from_string(os.environ.get(\"REDASH_ADDITIONAL_QUERY_RUNNERS\", \"\"))\n\nQUERY_RUNNERS = distinct(enabled_query_runners + additional_query_runners)\n\n# Support for Sentry (http://getsentry.com/). Just set your Sentry DSN to enable it:\nSENTRY_DSN = os.environ.get(\"REDASH_SENTRY_DSN\", \"\")\n\n# Client side toggles:\nALLOW_SCRIPTS_IN_USER_INPUT = parse_boolean(os.environ.get(\"REDASH_ALLOW_SCRIPTS_IN_USER_INPUT\", \"false\"))\nCLIENT_SIDE_METRICS = parse_boolean(os.environ.get(\"REDASH_CLIENT_SIDE_METRICS\", \"false\"))\n# http://api.highcharts.com/highcharts#plotOptions.series.turboThreshold\nHIGHCHARTS_TURBO_THRESHOLD = int(os.environ.get(\"REDASH_HIGHCHARTS_TURBO_THRESHOLD\", \"1000\"))\n\n# Features:\nFEATURE_ALLOW_ALL_TO_EDIT_QUERIES = parse_boolean(os.environ.get(\"REDASH_FEATURE_ALLOW_ALL_TO_EDIT\", \"true\"))\nFEATURE_TABLES_PERMISSIONS = parse_boolean(os.environ.get(\"REDASH_FEATURE_TABLES_PERMISSIONS\", \"false\"))\n\n# BigQuery\nBIGQUERY_HTTP_TIMEOUT = int(os.environ.get(\"REDASH_BIGQUERY_HTTP_TIMEOUT\", \"600\"))\n", "path": "redash/settings.py"}]}