deploying docs: chore(celery): Cleanup config and async query specifications (#25314) (apache/superset@1e37f0b41782d35d68f657bfa87aeb9055d1e6e7)
diff --git a/404.html b/404.html
index 6b8606c..2a4fa77 100644
--- a/404.html
+++ b/404.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -45,7 +45,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/assets/js/6432bc55.ace5d07c.js b/assets/js/6432bc55.cb5cd157.js
similarity index 66%
rename from assets/js/6432bc55.ace5d07c.js
rename to assets/js/6432bc55.cb5cd157.js
index 2ca1886..ff9704e 100644
--- a/assets/js/6432bc55.ace5d07c.js
+++ b/assets/js/6432bc55.cb5cd157.js
@@ -1 +1 @@
-"use strict";(self.webpackChunkdocs_v_2=self.webpackChunkdocs_v_2||[]).push([[4003],{40424:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>d,frontMatter:()=>i,metadata:()=>o,toc:()=>c});var a=n(83117),r=(n(67294),n(3905));const i={title:"Caching",hide_title:!0,sidebar_position:6,version:1},l=void 0,o={unversionedId:"installation/cache",id:"installation/cache",title:"Caching",description:"Caching",source:"@site/docs/installation/cache.mdx",sourceDirName:"installation",slug:"/installation/cache",permalink:"/docs/installation/cache",draft:!1,editUrl:"https://github.com/apache/superset/tree/master/docs/docs/installation/cache.mdx",tags:[],version:"current",sidebarPosition:6,frontMatter:{title:"Caching",hide_title:!0,sidebar_position:6,version:1},sidebar:"tutorialSidebar",previous:{title:"Additional Networking Settings",permalink:"/docs/installation/networking-settings"},next:{title:"Event Logging",permalink:"/docs/installation/event-logging"}},s={},c=[{value:"Caching",id:"caching",level:2},{value:"Dependencies",id:"dependencies",level:3},{value:"Fallback Metastore Cache",id:"fallback-metastore-cache",level:3},{value:"Chart Cache Timeout",id:"chart-cache-timeout",level:3},{value:"SQL Lab Query Results",id:"sql-lab-query-results",level:3},{value:"Caching Thumbnails",id:"caching-thumbnails",level:3}],u={toc:c},p="wrapper";function d(e){let{components:t,...n}=e;return(0,r.kt)(p,(0,a.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h2",{id:"caching"},"Caching"),(0,r.kt)("p",null,"Superset uses ",(0,r.kt)("a",{parentName:"p",href:"https://flask-caching.readthedocs.io/"},"Flask-Caching")," for caching purposes.\nFlask-Caching supports various caching backends, including Redis (recommended), Memcached,\nSimpleCache (in-memory), or the local filesystem.\n",(0,r.kt)("a",{parentName:"p",href:"https://flask-caching.readthedocs.io/en/latest/#custom-cache-backends"},"Custom cache backends"),"\nare also supported."),(0,r.kt)("p",null,"Caching can be configured by providing a dictionaries in\n",(0,r.kt)("inlineCode",{parentName:"p"},"superset_config.py")," that comply with",(0,r.kt)("a",{parentName:"p",href:"https://flask-caching.readthedocs.io/en/latest/#configuring-flask-caching"},"the Flask-Caching config specifications"),"."),(0,r.kt)("p",null,"The following cache configurations can be customized in this way:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Dashboard filter state (required): ",(0,r.kt)("inlineCode",{parentName:"li"},"FILTER_STATE_CACHE_CONFIG"),"."),(0,r.kt)("li",{parentName:"ul"},"Explore chart form data (required): ",(0,r.kt)("inlineCode",{parentName:"li"},"EXPLORE_FORM_DATA_CACHE_CONFIG")),(0,r.kt)("li",{parentName:"ul"},"Metadata cache (optional): ",(0,r.kt)("inlineCode",{parentName:"li"},"CACHE_CONFIG")),(0,r.kt)("li",{parentName:"ul"},"Charting data queried from datasets (optional): ",(0,r.kt)("inlineCode",{parentName:"li"},"DATA_CACHE_CONFIG"))),(0,r.kt)("p",null,"For example, to configure the filter state cache using redis:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},"FILTER_STATE_CACHE_CONFIG = {\n    'CACHE_TYPE': 'RedisCache',\n    'CACHE_DEFAULT_TIMEOUT': 86400,\n    'CACHE_KEY_PREFIX': 'superset_filter_cache',\n    'CACHE_REDIS_URL': 'redis://localhost:6379/0'\n}\n")),(0,r.kt)("h3",{id:"dependencies"},"Dependencies"),(0,r.kt)("p",null,"In order to use dedicated cache stores, additional python libraries must be installed"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"For Redis: we recommend the ",(0,r.kt)("a",{parentName:"li",href:"https://pypi.python.org/pypi/redis"},"redis")," Python package"),(0,r.kt)("li",{parentName:"ul"},"Memcached: we recommend using ",(0,r.kt)("a",{parentName:"li",href:"https://pypi.org/project/pylibmc/"},"pylibmc")," client library as\n",(0,r.kt)("inlineCode",{parentName:"li"},"python-memcached")," does not handle storing binary data correctly.")),(0,r.kt)("p",null,"These libraries can be installed using pip."),(0,r.kt)("h3",{id:"fallback-metastore-cache"},"Fallback Metastore Cache"),(0,r.kt)("p",null,"Note, that some form of Filter State and Explore caching are required. If either of these caches\nare undefined, Superset falls back to using a built-in cache that stores data in the metadata\ndatabase. While it is recommended to use a dedicated cache, the built-in cache can also be used\nto cache other data."),(0,r.kt)("p",null,"For example, to use the built-in cache to store chart data, use the following config:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'DATA_CACHE_CONFIG = {\n    "CACHE_TYPE": "SupersetMetastoreCache",\n    "CACHE_KEY_PREFIX": "superset_results",  # make sure this string is unique to avoid collisions\n    "CACHE_DEFAULT_TIMEOUT": 86400,  # 60 seconds * 60 minutes * 24 hours\n}\n')),(0,r.kt)("h3",{id:"chart-cache-timeout"},"Chart Cache Timeout"),(0,r.kt)("p",null,"The cache timeout for charts may be overridden by the settings for an individual chart, dataset, or\ndatabase. Each of these configurations will be checked in order before falling back to the default\nvalue defined in `DATA_CACHE_CONFIG."),(0,r.kt)("p",null,"Note, that by setting the cache timeout to ",(0,r.kt)("inlineCode",{parentName:"p"},"-1"),", caching for charting data can be disabled, either\nper chart, dataset or database, or by default if set in ",(0,r.kt)("inlineCode",{parentName:"p"},"DATA_CACHE_CONFIG"),"."),(0,r.kt)("h3",{id:"sql-lab-query-results"},"SQL Lab Query Results"),(0,r.kt)("p",null,"Caching for SQL Lab query results is used when async queries are enabled and is configured using\n",(0,r.kt)("inlineCode",{parentName:"p"},"RESULTS_BACKEND"),"."),(0,r.kt)("p",null,"Note that this configuration does not use a flask-caching dictionary for its configuration, but\ninstead requires a cachelib object."),(0,r.kt)("p",null,"See ",(0,r.kt)("a",{parentName:"p",href:"/docs/installation/async-queries-celery"},"Async Queries via Celery")," for details."),(0,r.kt)("h3",{id:"caching-thumbnails"},"Caching Thumbnails"),(0,r.kt)("p",null,"This is an optional feature that can be turned on by activating it\u2019s ",(0,r.kt)("a",{parentName:"p",href:"https://superset.apache.org/docs/installation/configuring-superset#feature-flags"},"feature flag")," on config:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'FEATURE_FLAGS = {\n    "THUMBNAILS": True,\n    "THUMBNAILS_SQLA_LISTENERS": True,\n}\n')),(0,r.kt)("p",null,"By default thumbnails are rendered per user, and will fall back to the Selenium user for anonymous users.\nTo always render thumbnails as a fixed user (",(0,r.kt)("inlineCode",{parentName:"p"},"admin")," in this example), use the following configuration:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'from superset.tasks.types import ExecutorType\n\nTHUMBNAIL_SELENIUM_USER = "admin"\nTHUMBNAIL_EXECUTE_AS = [ExecutorType.SELENIUM]\n')),(0,r.kt)("p",null,"For this feature you will need a cache system and celery workers. All thumbnails are stored on cache\nand are processed asynchronously by the workers."),(0,r.kt)("p",null,"An example config where images are stored on S3 could be:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'from flask import Flask\nfrom s3cache.s3cache import S3Cache\n\n...\n\nclass CeleryConfig(object):\n    broker_url = "redis://localhost:6379/0"\n    imports = ("superset.sql_lab", "superset.tasks", "superset.tasks.thumbnails")\n    result_backend = "redis://localhost:6379/0"\n    worker_prefetch_multiplier = 10\n    task_acks_late = True\n\n\nCELERY_CONFIG = CeleryConfig\n\ndef init_thumbnail_cache(app: Flask) -> S3Cache:\n    return S3Cache("bucket_name", \'thumbs_cache/\')\n\n\nTHUMBNAIL_CACHE_CONFIG = init_thumbnail_cache\n# Async selenium thumbnail task will use the following user\nTHUMBNAIL_SELENIUM_USER = "Admin"\n')),(0,r.kt)("p",null,"Using the above example cache keys for dashboards will be ",(0,r.kt)("inlineCode",{parentName:"p"},"superset_thumb__dashboard__{ID}"),". You can\noverride the base URL for selenium using:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'WEBDRIVER_BASEURL = "https://superset.company.com"\n')),(0,r.kt)("p",null,"Additional selenium web drive configuration can be set using ",(0,r.kt)("inlineCode",{parentName:"p"},"WEBDRIVER_CONFIGURATION"),". You can\nimplement a custom function to authenticate selenium. The default function uses the ",(0,r.kt)("inlineCode",{parentName:"p"},"flask-login"),"\nsession cookie. Here's an example of a custom function signature:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'def auth_driver(driver: WebDriver, user: "User") -> WebDriver:\n    pass\n')),(0,r.kt)("p",null,"Then on configuration:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"WEBDRIVER_AUTH_FUNC = auth_driver\n")))}d.isMDXComponent=!0},3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function o(e,t){if(null==e)return{};var n,a,r=function(e,t){if(null==e)return{};var n,a,r={},i=Object.keys(e);for(a=0;a<i.length;a++)n=i[a],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a<i.length;a++)n=i[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),c=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},u=function(e){var t=c(e.components);return a.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,u=o(e,["components","mdxType","originalType","parentName"]),p=c(n),h=r,m=p["".concat(s,".").concat(h)]||p[h]||d[h]||i;return n?a.createElement(m,l(l({ref:t},u),{},{components:n})):a.createElement(m,l({ref:t},u))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,l=new Array(i);l[0]=h;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[p]="string"==typeof e?e:r,l[1]=o;for(var c=2;c<i;c++)l[c]=n[c];return a.createElement.apply(null,l)}return a.createElement.apply(null,n)}h.displayName="MDXCreateElement"}}]);
\ No newline at end of file
+"use strict";(self.webpackChunkdocs_v_2=self.webpackChunkdocs_v_2||[]).push([[4003],{40424:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>d,frontMatter:()=>i,metadata:()=>o,toc:()=>c});var a=n(83117),r=(n(67294),n(3905));const i={title:"Caching",hide_title:!0,sidebar_position:6,version:1},l=void 0,o={unversionedId:"installation/cache",id:"installation/cache",title:"Caching",description:"Caching",source:"@site/docs/installation/cache.mdx",sourceDirName:"installation",slug:"/installation/cache",permalink:"/docs/installation/cache",draft:!1,editUrl:"https://github.com/apache/superset/tree/master/docs/docs/installation/cache.mdx",tags:[],version:"current",sidebarPosition:6,frontMatter:{title:"Caching",hide_title:!0,sidebar_position:6,version:1},sidebar:"tutorialSidebar",previous:{title:"Additional Networking Settings",permalink:"/docs/installation/networking-settings"},next:{title:"Event Logging",permalink:"/docs/installation/event-logging"}},s={},c=[{value:"Caching",id:"caching",level:2},{value:"Dependencies",id:"dependencies",level:3},{value:"Fallback Metastore Cache",id:"fallback-metastore-cache",level:3},{value:"Chart Cache Timeout",id:"chart-cache-timeout",level:3},{value:"SQL Lab Query Results",id:"sql-lab-query-results",level:3},{value:"Caching Thumbnails",id:"caching-thumbnails",level:3}],u={toc:c},p="wrapper";function d(e){let{components:t,...n}=e;return(0,r.kt)(p,(0,a.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h2",{id:"caching"},"Caching"),(0,r.kt)("p",null,"Superset uses ",(0,r.kt)("a",{parentName:"p",href:"https://flask-caching.readthedocs.io/"},"Flask-Caching")," for caching purposes.\nFlask-Caching supports various caching backends, including Redis (recommended), Memcached,\nSimpleCache (in-memory), or the local filesystem.\n",(0,r.kt)("a",{parentName:"p",href:"https://flask-caching.readthedocs.io/en/latest/#custom-cache-backends"},"Custom cache backends"),"\nare also supported."),(0,r.kt)("p",null,"Caching can be configured by providing a dictionaries in\n",(0,r.kt)("inlineCode",{parentName:"p"},"superset_config.py")," that comply with",(0,r.kt)("a",{parentName:"p",href:"https://flask-caching.readthedocs.io/en/latest/#configuring-flask-caching"},"the Flask-Caching config specifications"),"."),(0,r.kt)("p",null,"The following cache configurations can be customized in this way:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Dashboard filter state (required): ",(0,r.kt)("inlineCode",{parentName:"li"},"FILTER_STATE_CACHE_CONFIG"),"."),(0,r.kt)("li",{parentName:"ul"},"Explore chart form data (required): ",(0,r.kt)("inlineCode",{parentName:"li"},"EXPLORE_FORM_DATA_CACHE_CONFIG")),(0,r.kt)("li",{parentName:"ul"},"Metadata cache (optional): ",(0,r.kt)("inlineCode",{parentName:"li"},"CACHE_CONFIG")),(0,r.kt)("li",{parentName:"ul"},"Charting data queried from datasets (optional): ",(0,r.kt)("inlineCode",{parentName:"li"},"DATA_CACHE_CONFIG"))),(0,r.kt)("p",null,"For example, to configure the filter state cache using redis:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},"FILTER_STATE_CACHE_CONFIG = {\n    'CACHE_TYPE': 'RedisCache',\n    'CACHE_DEFAULT_TIMEOUT': 86400,\n    'CACHE_KEY_PREFIX': 'superset_filter_cache',\n    'CACHE_REDIS_URL': 'redis://localhost:6379/0'\n}\n")),(0,r.kt)("h3",{id:"dependencies"},"Dependencies"),(0,r.kt)("p",null,"In order to use dedicated cache stores, additional python libraries must be installed"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"For Redis: we recommend the ",(0,r.kt)("a",{parentName:"li",href:"https://pypi.python.org/pypi/redis"},"redis")," Python package"),(0,r.kt)("li",{parentName:"ul"},"Memcached: we recommend using ",(0,r.kt)("a",{parentName:"li",href:"https://pypi.org/project/pylibmc/"},"pylibmc")," client library as\n",(0,r.kt)("inlineCode",{parentName:"li"},"python-memcached")," does not handle storing binary data correctly.")),(0,r.kt)("p",null,"These libraries can be installed using pip."),(0,r.kt)("h3",{id:"fallback-metastore-cache"},"Fallback Metastore Cache"),(0,r.kt)("p",null,"Note, that some form of Filter State and Explore caching are required. If either of these caches\nare undefined, Superset falls back to using a built-in cache that stores data in the metadata\ndatabase. While it is recommended to use a dedicated cache, the built-in cache can also be used\nto cache other data."),(0,r.kt)("p",null,"For example, to use the built-in cache to store chart data, use the following config:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'DATA_CACHE_CONFIG = {\n    "CACHE_TYPE": "SupersetMetastoreCache",\n    "CACHE_KEY_PREFIX": "superset_results",  # make sure this string is unique to avoid collisions\n    "CACHE_DEFAULT_TIMEOUT": 86400,  # 60 seconds * 60 minutes * 24 hours\n}\n')),(0,r.kt)("h3",{id:"chart-cache-timeout"},"Chart Cache Timeout"),(0,r.kt)("p",null,"The cache timeout for charts may be overridden by the settings for an individual chart, dataset, or\ndatabase. Each of these configurations will be checked in order before falling back to the default\nvalue defined in `DATA_CACHE_CONFIG."),(0,r.kt)("p",null,"Note, that by setting the cache timeout to ",(0,r.kt)("inlineCode",{parentName:"p"},"-1"),", caching for charting data can be disabled, either\nper chart, dataset or database, or by default if set in ",(0,r.kt)("inlineCode",{parentName:"p"},"DATA_CACHE_CONFIG"),"."),(0,r.kt)("h3",{id:"sql-lab-query-results"},"SQL Lab Query Results"),(0,r.kt)("p",null,"Caching for SQL Lab query results is used when async queries are enabled and is configured using\n",(0,r.kt)("inlineCode",{parentName:"p"},"RESULTS_BACKEND"),"."),(0,r.kt)("p",null,"Note that this configuration does not use a flask-caching dictionary for its configuration, but\ninstead requires a cachelib object."),(0,r.kt)("p",null,"See ",(0,r.kt)("a",{parentName:"p",href:"/docs/installation/async-queries-celery"},"Async Queries via Celery")," for details."),(0,r.kt)("h3",{id:"caching-thumbnails"},"Caching Thumbnails"),(0,r.kt)("p",null,"This is an optional feature that can be turned on by activating it\u2019s ",(0,r.kt)("a",{parentName:"p",href:"https://superset.apache.org/docs/installation/configuring-superset#feature-flags"},"feature flag")," on config:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'FEATURE_FLAGS = {\n    "THUMBNAILS": True,\n    "THUMBNAILS_SQLA_LISTENERS": True,\n}\n')),(0,r.kt)("p",null,"By default thumbnails are rendered per user, and will fall back to the Selenium user for anonymous users.\nTo always render thumbnails as a fixed user (",(0,r.kt)("inlineCode",{parentName:"p"},"admin")," in this example), use the following configuration:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'from superset.tasks.types import ExecutorType\n\nTHUMBNAIL_SELENIUM_USER = "admin"\nTHUMBNAIL_EXECUTE_AS = [ExecutorType.SELENIUM]\n')),(0,r.kt)("p",null,"For this feature you will need a cache system and celery workers. All thumbnails are stored on cache\nand are processed asynchronously by the workers."),(0,r.kt)("p",null,"An example config where images are stored on S3 could be:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'from flask import Flask\nfrom s3cache.s3cache import S3Cache\n\n...\n\nclass CeleryConfig(object):\n    broker_url = "redis://localhost:6379/0"\n    imports = (\n        "superset.sql_lab",\n        "superset.tasks.thumbnails",\n    )\n    result_backend = "redis://localhost:6379/0"\n    worker_prefetch_multiplier = 10\n    task_acks_late = True\n\n\nCELERY_CONFIG = CeleryConfig\n\ndef init_thumbnail_cache(app: Flask) -> S3Cache:\n    return S3Cache("bucket_name", \'thumbs_cache/\')\n\n\nTHUMBNAIL_CACHE_CONFIG = init_thumbnail_cache\n# Async selenium thumbnail task will use the following user\nTHUMBNAIL_SELENIUM_USER = "Admin"\n')),(0,r.kt)("p",null,"Using the above example cache keys for dashboards will be ",(0,r.kt)("inlineCode",{parentName:"p"},"superset_thumb__dashboard__{ID}"),". You can\noverride the base URL for selenium using:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'WEBDRIVER_BASEURL = "https://superset.company.com"\n')),(0,r.kt)("p",null,"Additional selenium web drive configuration can be set using ",(0,r.kt)("inlineCode",{parentName:"p"},"WEBDRIVER_CONFIGURATION"),". You can\nimplement a custom function to authenticate selenium. The default function uses the ",(0,r.kt)("inlineCode",{parentName:"p"},"flask-login"),"\nsession cookie. Here's an example of a custom function signature:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},'def auth_driver(driver: WebDriver, user: "User") -> WebDriver:\n    pass\n')),(0,r.kt)("p",null,"Then on configuration:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"WEBDRIVER_AUTH_FUNC = auth_driver\n")))}d.isMDXComponent=!0},3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function o(e,t){if(null==e)return{};var n,a,r=function(e,t){if(null==e)return{};var n,a,r={},i=Object.keys(e);for(a=0;a<i.length;a++)n=i[a],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a<i.length;a++)n=i[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),c=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},u=function(e){var t=c(e.components);return a.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,u=o(e,["components","mdxType","originalType","parentName"]),p=c(n),h=r,m=p["".concat(s,".").concat(h)]||p[h]||d[h]||i;return n?a.createElement(m,l(l({ref:t},u),{},{components:n})):a.createElement(m,l({ref:t},u))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,l=new Array(i);l[0]=h;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[p]="string"==typeof e?e:r,l[1]=o;for(var c=2;c<i;c++)l[c]=n[c];return a.createElement.apply(null,l)}return a.createElement.apply(null,n)}h.displayName="MDXCreateElement"}}]);
\ No newline at end of file
diff --git a/assets/js/cd90435d.99f961ac.js b/assets/js/cd90435d.99f961ac.js
deleted file mode 100644
index 9d626c4..0000000
--- a/assets/js/cd90435d.99f961ac.js
+++ /dev/null
@@ -1 +0,0 @@
-"use strict";(self.webpackChunkdocs_v_2=self.webpackChunkdocs_v_2||[]).push([[3909],{46006:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>y,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var n=r(83117),a=(r(67294),r(3905));const o={title:"Async Queries via Celery",hide_title:!0,sidebar_position:9,version:1},s=void 0,i={unversionedId:"installation/async-queries-celery",id:"installation/async-queries-celery",title:"Async Queries via Celery",description:"Async Queries via Celery",source:"@site/docs/installation/async-queries-celery.mdx",sourceDirName:"installation",slug:"/installation/async-queries-celery",permalink:"/docs/installation/async-queries-celery",draft:!1,editUrl:"https://github.com/apache/superset/tree/master/docs/docs/installation/async-queries-celery.mdx",tags:[],version:"current",sidebarPosition:9,frontMatter:{title:"Async Queries via Celery",hide_title:!0,sidebar_position:9,version:1},sidebar:"tutorialSidebar",previous:{title:"Upgrading Superset",permalink:"/docs/installation/upgrading-superset"},next:{title:"Alerts and Reports",permalink:"/docs/installation/alerts-reports"}},l={},c=[{value:"Async Queries via Celery",id:"async-queries-via-celery",level:2},{value:"Celery",id:"celery",level:3},{value:"Celery Flower",id:"celery-flower",level:3}],p={toc:c},u="wrapper";function y(e){let{components:t,...r}=e;return(0,a.kt)(u,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h2",{id:"async-queries-via-celery"},"Async Queries via Celery"),(0,a.kt)("h3",{id:"celery"},"Celery"),(0,a.kt)("p",null,"On large analytic databases, it\u2019s common to run queries that execute for minutes or hours. To enable\nsupport for long running queries that execute beyond the typical web request\u2019s timeout (30-60\nseconds), it is necessary to configure an asynchronous backend for Superset which consists of:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"one or many Superset workers (which is implemented as a Celery worker), and can be started with\nthe ",(0,a.kt)("inlineCode",{parentName:"li"},"celery worker")," command, run ",(0,a.kt)("inlineCode",{parentName:"li"},"celery worker --help")," to view the related options."),(0,a.kt)("li",{parentName:"ul"},"a celery broker (message queue) for which we recommend using Redis or RabbitMQ"),(0,a.kt)("li",{parentName:"ul"},"a results backend that defines where the worker will persist the query results")),(0,a.kt)("p",null,"Configuring Celery requires defining a ",(0,a.kt)("inlineCode",{parentName:"p"},"CELERY_CONFIG")," in your ",(0,a.kt)("inlineCode",{parentName:"p"},"superset_config.py"),". Both the worker\nand web server processes should have the same configuration."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},"class CeleryConfig(object):\n    broker_url = 'redis://localhost:6379/0'\n    imports = (\n        'superset.sql_lab',\n        'superset.tasks',\n    )\n    result_backend = 'redis://localhost:6379/0'\n    worker_log_level = 'DEBUG'\n    worker_prefetch_multiplier = 10\n    task_acks_late = True\n    task_annotations = {\n        'sql_lab.get_sql_results': {\n            'rate_limit': '100/s',\n        },\n        'email_reports.send': {\n            'rate_limit': '1/s',\n            'time_limit': 120,\n            'soft_time_limit': 150,\n            'ignore_result': True,\n        },\n    }\n    beat_schedule = {\n        'email_reports.schedule_hourly': {\n            'task': 'email_reports.schedule_hourly',\n            'schedule': crontab(minute=1, hour='*'),\n        },\n    }\n\nCELERY_CONFIG = CeleryConfig\n")),(0,a.kt)("p",null,"To start a Celery worker to leverage the configuration, run the following command:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"celery --app=superset.tasks.celery_app:app worker --pool=prefork -O fair -c 4\n")),(0,a.kt)("p",null,"To start a job which schedules periodic background jobs, run the following command:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"celery --app=superset.tasks.celery_app:app beat\n")),(0,a.kt)("p",null,"To setup a result backend, you need to pass an instance of a derivative of from\nfrom flask_caching.backends.base import BaseCache to the RESULTS_BACKEND configuration key in your superset_config.py. You can\nuse Memcached, Redis, S3 (",(0,a.kt)("a",{parentName:"p",href:"https://pypi.python.org/pypi/s3werkzeugcache"},"https://pypi.python.org/pypi/s3werkzeugcache"),"), memory or the file system\n(in a single server-type setup or for testing), or to write your own caching interface. Your\n",(0,a.kt)("inlineCode",{parentName:"p"},"superset_config.py")," may look something like:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},"# On S3\nfrom s3cache.s3cache import S3Cache\nS3_CACHE_BUCKET = 'foobar-superset'\nS3_CACHE_KEY_PREFIX = 'sql_lab_result'\nRESULTS_BACKEND = S3Cache(S3_CACHE_BUCKET, S3_CACHE_KEY_PREFIX)\n\n# On Redis\nfrom flask_caching.backends.rediscache import RedisCache\nRESULTS_BACKEND = RedisCache(\n    host='localhost', port=6379, key_prefix='superset_results')\n")),(0,a.kt)("p",null,"For performance gains, ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/msgpack/msgpack-python"},"MessagePack")," and\n",(0,a.kt)("a",{parentName:"p",href:"https://arrow.apache.org/docs/python/"},"PyArrow")," are now used for results serialization. This can be\ndisabled by setting ",(0,a.kt)("inlineCode",{parentName:"p"},"RESULTS_BACKEND_USE_MSGPACK = False")," in your ",(0,a.kt)("inlineCode",{parentName:"p"},"superset_config.py"),", should any\nissues arise. Please clear your existing results cache store when upgrading an existing environment."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Important Notes")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"It is important that all the worker nodes and web servers in the Superset cluster ",(0,a.kt)("em",{parentName:"p"},"share a common\nmetadata database"),". This means that SQLite will not work in this context since it has limited\nsupport for concurrency and typically lives on the local file system.")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"There should ",(0,a.kt)("em",{parentName:"p"},"only be one instance of celery beat running")," in your entire setup. If not,\nbackground jobs can get scheduled multiple times resulting in weird behaviors like duplicate\ndelivery of reports, higher than expected load / traffic etc.")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"SQL Lab will ",(0,a.kt)("em",{parentName:"p"},"only run your queries asynchronously if")," you enable ",(0,a.kt)("strong",{parentName:"p"},"Asynchronous Query Execution"),"\nin your database settings (Sources > Databases > Edit record)."))),(0,a.kt)("h3",{id:"celery-flower"},"Celery Flower"),(0,a.kt)("p",null,"Flower is a web based tool for monitoring the Celery cluster which you can install from pip:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},"pip install flower\n")),(0,a.kt)("p",null,"You can run flower using:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"celery --app=superset.tasks.celery_app:app flower\n")))}y.isMDXComponent=!0},3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>d});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function i(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},u="mdxType",y={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=c(r),m=a,d=u["".concat(l,".").concat(m)]||u[m]||y[m]||o;return r?n.createElement(d,s(s({ref:t},p),{},{components:r})):n.createElement(d,s({ref:t},p))}));function d(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=m;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[u]="string"==typeof e?e:a,s[1]=i;for(var c=2;c<o;c++)s[c]=r[c];return n.createElement.apply(null,s)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"}}]);
\ No newline at end of file
diff --git a/assets/js/cd90435d.ab34b154.js b/assets/js/cd90435d.ab34b154.js
new file mode 100644
index 0000000..aea4c12
--- /dev/null
+++ b/assets/js/cd90435d.ab34b154.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_v_2=self.webpackChunkdocs_v_2||[]).push([[3909],{46006:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>y,frontMatter:()=>o,metadata:()=>i,toc:()=>p});var n=r(83117),a=(r(67294),r(3905));const o={title:"Async Queries via Celery",hide_title:!0,sidebar_position:9,version:1},s=void 0,i={unversionedId:"installation/async-queries-celery",id:"installation/async-queries-celery",title:"Async Queries via Celery",description:"Async Queries via Celery",source:"@site/docs/installation/async-queries-celery.mdx",sourceDirName:"installation",slug:"/installation/async-queries-celery",permalink:"/docs/installation/async-queries-celery",draft:!1,editUrl:"https://github.com/apache/superset/tree/master/docs/docs/installation/async-queries-celery.mdx",tags:[],version:"current",sidebarPosition:9,frontMatter:{title:"Async Queries via Celery",hide_title:!0,sidebar_position:9,version:1},sidebar:"tutorialSidebar",previous:{title:"Upgrading Superset",permalink:"/docs/installation/upgrading-superset"},next:{title:"Alerts and Reports",permalink:"/docs/installation/alerts-reports"}},l={},p=[{value:"Async Queries via Celery",id:"async-queries-via-celery",level:2},{value:"Celery",id:"celery",level:3},{value:"Celery Flower",id:"celery-flower",level:3}],c={toc:p},u="wrapper";function y(e){let{components:t,...r}=e;return(0,a.kt)(u,(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h2",{id:"async-queries-via-celery"},"Async Queries via Celery"),(0,a.kt)("h3",{id:"celery"},"Celery"),(0,a.kt)("p",null,"On large analytic databases, it\u2019s common to run queries that execute for minutes or hours. To enable\nsupport for long running queries that execute beyond the typical web request\u2019s timeout (30-60\nseconds), it is necessary to configure an asynchronous backend for Superset which consists of:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"one or many Superset workers (which is implemented as a Celery worker), and can be started with\nthe ",(0,a.kt)("inlineCode",{parentName:"li"},"celery worker")," command, run ",(0,a.kt)("inlineCode",{parentName:"li"},"celery worker --help")," to view the related options."),(0,a.kt)("li",{parentName:"ul"},"a celery broker (message queue) for which we recommend using Redis or RabbitMQ"),(0,a.kt)("li",{parentName:"ul"},"a results backend that defines where the worker will persist the query results")),(0,a.kt)("p",null,"Configuring Celery requires defining a ",(0,a.kt)("inlineCode",{parentName:"p"},"CELERY_CONFIG")," in your ",(0,a.kt)("inlineCode",{parentName:"p"},"superset_config.py"),". Both the worker\nand web server processes should have the same configuration."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'class CeleryConfig(object):\n    broker_url = "redis://localhost:6379/0"\n    imports = (\n        "superset.sql_lab",\n        "superset.tasks.scheduler",\n    )\n    result_backend = "redis://localhost:6379/0"\n    worker_prefetch_multiplier = 10\n    task_acks_late = True\n    task_annotations = {\n        "sql_lab.get_sql_results": {\n            "rate_limit": "100/s",\n        },\n    }\n\nCELERY_CONFIG = CeleryConfig\n')),(0,a.kt)("p",null,"To start a Celery worker to leverage the configuration, run the following command:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"celery --app=superset.tasks.celery_app:app worker --pool=prefork -O fair -c 4\n")),(0,a.kt)("p",null,"To start a job which schedules periodic background jobs, run the following command:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"celery --app=superset.tasks.celery_app:app beat\n")),(0,a.kt)("p",null,"To setup a result backend, you need to pass an instance of a derivative of from\nfrom flask_caching.backends.base import BaseCache to the RESULTS_BACKEND configuration key in your superset_config.py. You can\nuse Memcached, Redis, S3 (",(0,a.kt)("a",{parentName:"p",href:"https://pypi.python.org/pypi/s3werkzeugcache"},"https://pypi.python.org/pypi/s3werkzeugcache"),"), memory or the file system\n(in a single server-type setup or for testing), or to write your own caching interface. Your\n",(0,a.kt)("inlineCode",{parentName:"p"},"superset_config.py")," may look something like:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},"# On S3\nfrom s3cache.s3cache import S3Cache\nS3_CACHE_BUCKET = 'foobar-superset'\nS3_CACHE_KEY_PREFIX = 'sql_lab_result'\nRESULTS_BACKEND = S3Cache(S3_CACHE_BUCKET, S3_CACHE_KEY_PREFIX)\n\n# On Redis\nfrom flask_caching.backends.rediscache import RedisCache\nRESULTS_BACKEND = RedisCache(\n    host='localhost', port=6379, key_prefix='superset_results')\n")),(0,a.kt)("p",null,"For performance gains, ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/msgpack/msgpack-python"},"MessagePack")," and\n",(0,a.kt)("a",{parentName:"p",href:"https://arrow.apache.org/docs/python/"},"PyArrow")," are now used for results serialization. This can be\ndisabled by setting ",(0,a.kt)("inlineCode",{parentName:"p"},"RESULTS_BACKEND_USE_MSGPACK = False")," in your ",(0,a.kt)("inlineCode",{parentName:"p"},"superset_config.py"),", should any\nissues arise. Please clear your existing results cache store when upgrading an existing environment."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Important Notes")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"It is important that all the worker nodes and web servers in the Superset cluster ",(0,a.kt)("em",{parentName:"p"},"share a common\nmetadata database"),". This means that SQLite will not work in this context since it has limited\nsupport for concurrency and typically lives on the local file system.")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"There should ",(0,a.kt)("em",{parentName:"p"},"only be one instance of celery beat running")," in your entire setup. If not,\nbackground jobs can get scheduled multiple times resulting in weird behaviors like duplicate\ndelivery of reports, higher than expected load / traffic etc.")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"SQL Lab will ",(0,a.kt)("em",{parentName:"p"},"only run your queries asynchronously if")," you enable ",(0,a.kt)("strong",{parentName:"p"},"Asynchronous Query Execution"),"\nin your database settings (Sources > Databases > Edit record)."))),(0,a.kt)("h3",{id:"celery-flower"},"Celery Flower"),(0,a.kt)("p",null,"Flower is a web based tool for monitoring the Celery cluster which you can install from pip:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},"pip install flower\n")),(0,a.kt)("p",null,"You can run flower using:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"celery --app=superset.tasks.celery_app:app flower\n")))}y.isMDXComponent=!0},3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>m});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function i(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),p=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},c=function(e){var t=p(e.components);return n.createElement(l.Provider,{value:t},e.children)},u="mdxType",y={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),u=p(r),d=a,m=u["".concat(l,".").concat(d)]||u[d]||y[d]||o;return r?n.createElement(m,s(s({ref:t},c),{},{components:r})):n.createElement(m,s({ref:t},c))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=d;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[u]="string"==typeof e?e:a,s[1]=i;for(var p=2;p<o;p++)s[p]=r[p];return n.createElement.apply(null,s)}return n.createElement.apply(null,r)}d.displayName="MDXCreateElement"}}]);
\ No newline at end of file
diff --git a/assets/js/f9cc156b.be939da2.js b/assets/js/f9cc156b.be939da2.js
new file mode 100644
index 0000000..ecbba46
--- /dev/null
+++ b/assets/js/f9cc156b.be939da2.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs_v_2=self.webpackChunkdocs_v_2||[]).push([[8915],{6974:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>c,frontMatter:()=>o,metadata:()=>s,toc:()=>u});var r=n(83117),a=(n(67294),n(3905));const o={title:"Alerts and Reports",hide_title:!0,sidebar_position:10,version:2},i=void 0,s={unversionedId:"installation/alerts-reports",id:"installation/alerts-reports",title:"Alerts and Reports",description:"Alerts and Reports",source:"@site/docs/installation/alerts-reports.mdx",sourceDirName:"installation",slug:"/installation/alerts-reports",permalink:"/docs/installation/alerts-reports",draft:!1,editUrl:"https://github.com/apache/superset/tree/master/docs/docs/installation/alerts-reports.mdx",tags:[],version:"current",sidebarPosition:10,frontMatter:{title:"Alerts and Reports",hide_title:!0,sidebar_position:10,version:2},sidebar:"tutorialSidebar",previous:{title:"Async Queries via Celery",permalink:"/docs/installation/async-queries-celery"},next:{title:"SQL Templating",permalink:"/docs/installation/sql-templating"}},l={},u=[{value:"Alerts and Reports",id:"alerts-and-reports",level:2},{value:"Requirements",id:"requirements",level:3},{value:"Commons",id:"commons",level:4},{value:"In your <code>superset_config.py</code> or <code>superset_config_docker.py</code>",id:"in-your-superset_configpy-or-superset_config_dockerpy",level:5},{value:"Disable dry-run mode",id:"disable-dry-run-mode",level:6},{value:"In your <code>Dockerfile</code>",id:"in-your-dockerfile",level:5},{value:"Slack integration",id:"slack-integration",level:4},{value:"Kubernetes-specific",id:"kubernetes-specific",level:4},{value:"Docker Compose specific",id:"docker-compose-specific",level:4},{value:"You must have in your <code>docker-compose.yml</code>",id:"you-must-have-in-your-docker-composeyml",level:5},{value:"Detailed config",id:"detailed-config",level:3},{value:"Custom Dockerfile",id:"custom-dockerfile",level:3},{value:"Using Firefox",id:"using-firefox",level:4},{value:"Using Chrome",id:"using-chrome",level:4},{value:"Schedule Reports",id:"schedule-reports",level:3}],d={toc:u},p="wrapper";function c(e){let{components:t,...n}=e;return(0,a.kt)(p,(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h2",{id:"alerts-and-reports"},"Alerts and Reports"),(0,a.kt)("p",null,(0,a.kt)("em",{parentName:"p"},"This covers versions 1.0.1 to current.")),(0,a.kt)("p",null,"Users can configure automated alerts and reports to send dashboards or charts to an email recipient or Slack channel."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Alerts are sent when a SQL condition is reached"),(0,a.kt)("li",{parentName:"ul"},"Reports are sent on a schedule")),(0,a.kt)("p",null,"Alerts and reports are disabled by default. To turn them on, you need to do some setup, described here."),(0,a.kt)("h3",{id:"requirements"},"Requirements"),(0,a.kt)("h4",{id:"commons"},"Commons"),(0,a.kt)("h5",{id:"in-your-superset_configpy-or-superset_config_dockerpy"},"In your ",(0,a.kt)("inlineCode",{parentName:"h5"},"superset_config.py")," or ",(0,a.kt)("inlineCode",{parentName:"h5"},"superset_config_docker.py")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},'"ALERT_REPORTS"')," ",(0,a.kt)("a",{parentName:"li",href:"https://superset.apache.org/docs/installation/configuring-superset#feature-flags"},"feature flag")," must be turned to True."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"beat_schedule")," in CeleryConfig must contain schedule for ",(0,a.kt)("inlineCode",{parentName:"li"},"reports.scheduler"),"."),(0,a.kt)("li",{parentName:"ul"},"At least one of those must be configured, depending on what you want to use:",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"emails: ",(0,a.kt)("inlineCode",{parentName:"li"},"SMTP_*")," settings"),(0,a.kt)("li",{parentName:"ul"},"Slack messages: ",(0,a.kt)("inlineCode",{parentName:"li"},"SLACK_API_TOKEN"))))),(0,a.kt)("h6",{id:"disable-dry-run-mode"},"Disable dry-run mode"),(0,a.kt)("p",null,"Screenshots will be taken but no messages actually sent as long as ",(0,a.kt)("inlineCode",{parentName:"p"},"ALERT_REPORTS_NOTIFICATION_DRY_RUN = True"),", its default value in ",(0,a.kt)("inlineCode",{parentName:"p"},"docker/pythonpath_dev/superset_config.py"),".  To disable dry-run mode and start receiving email/Slack notifications, set ",(0,a.kt)("inlineCode",{parentName:"p"},"ALERT_REPORTS_NOTIFICATION_DRY_RUN")," to ",(0,a.kt)("inlineCode",{parentName:"p"},"False")," in ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/apache/superset/blob/master/docker/pythonpath_dev/superset_config.py"},"superset config"),"."),(0,a.kt)("h5",{id:"in-your-dockerfile"},"In your ",(0,a.kt)("inlineCode",{parentName:"h5"},"Dockerfile")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"You must install a headless browser, for taking screenshots of the charts and dashboards. Only Firefox and Chrome are currently supported.",(0,a.kt)("blockquote",{parentName:"li"},(0,a.kt)("p",{parentName:"blockquote"},"If you choose Chrome, you must also change the value of ",(0,a.kt)("inlineCode",{parentName:"p"},"WEBDRIVER_TYPE")," to ",(0,a.kt)("inlineCode",{parentName:"p"},'"chrome"')," in your ",(0,a.kt)("inlineCode",{parentName:"p"},"superset_config.py"),".")))),(0,a.kt)("p",null,"Note: All the components required (Firefox headless browser, Redis, Postgres db, celery worker and celery beat) are present in the ",(0,a.kt)("em",{parentName:"p"},"dev")," docker image if you are following ",(0,a.kt)("a",{parentName:"p",href:"https://superset.apache.org/docs/installation/installing-superset-using-docker-compose/"},"Installing Superset Locally"),".\nAll you need to do is add the required config variables described in this guide (See ",(0,a.kt)("inlineCode",{parentName:"p"},"Detailed Config"),")."),(0,a.kt)("p",null,"If you are running a non-dev docker image, e.g., a stable release like ",(0,a.kt)("inlineCode",{parentName:"p"},"apache/superset:2.0.1"),", that image does not include a headless browser.  Only the ",(0,a.kt)("inlineCode",{parentName:"p"},"superset_worker"),' container needs this headless browser to browse to the target chart or dashboard.\nYou can either install and configure the headless browser - see "Custom Dockerfile" section below - or when deploying via ',(0,a.kt)("inlineCode",{parentName:"p"},"docker compose"),", modify your ",(0,a.kt)("inlineCode",{parentName:"p"},"docker-compose.yml")," file to use a dev image for the worker container and a stable release image for the ",(0,a.kt)("inlineCode",{parentName:"p"},"superset_app")," container."),(0,a.kt)("p",null,(0,a.kt)("em",{parentName:"p"},"Note"),': In this context, a "dev image" is the same application software as its corresponding non-dev image, just bundled with additional tools.  So an image like ',(0,a.kt)("inlineCode",{parentName:"p"},"2.0.1-dev")," is identical to ",(0,a.kt)("inlineCode",{parentName:"p"},"2.0.1"),' when it comes to stability, functionality, and running in production.  The actual "in-development" versions of Superset - cutting-edge and unstable - are not tagged with version numbers on Docker Hub and will display version ',(0,a.kt)("inlineCode",{parentName:"p"},"0.0.0-dev")," within the Superset UI."),(0,a.kt)("h4",{id:"slack-integration"},"Slack integration"),(0,a.kt)("p",null,"To send alerts and reports to Slack channels, you need to create a new Slack Application on your workspace."),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Connect to your Slack workspace, then head to ",(0,a.kt)("a",{parentName:"li",href:"https://api.slack.com/apps"},"https://api.slack.com/apps"),"."),(0,a.kt)("li",{parentName:"ol"},"Create a new app."),(0,a.kt)("li",{parentName:"ol"},'Go to "OAuth & Permissions" section, and give the following scopes to your app:',(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"incoming-webhook")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"files:write")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"chat:write")))),(0,a.kt)("li",{parentName:"ol"},'At the top of the "OAuth and Permissions" section, click "install to workspace".'),(0,a.kt)("li",{parentName:"ol"},"Select a default channel for your app and continue.\n(You can post to any channel by inviting your Superset app into that channel)."),(0,a.kt)("li",{parentName:"ol"},'The app should now be installed in your workspace, and a "Bot User OAuth Access Token" should have been created. Copy that token in the ',(0,a.kt)("inlineCode",{parentName:"li"},"SLACK_API_TOKEN")," variable of your ",(0,a.kt)("inlineCode",{parentName:"li"},"superset_config.py"),"."),(0,a.kt)("li",{parentName:"ol"},"Restart the service (or run ",(0,a.kt)("inlineCode",{parentName:"li"},"superset init"),") to pull in the new configuration.")),(0,a.kt)("p",null,"Note: when you configure an alert or a report, the Slack channel list takes channel names without the leading '#' e.g. use ",(0,a.kt)("inlineCode",{parentName:"p"},"alerts")," instead of ",(0,a.kt)("inlineCode",{parentName:"p"},"#alerts"),"."),(0,a.kt)("h4",{id:"kubernetes-specific"},"Kubernetes-specific"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"You must have a ",(0,a.kt)("inlineCode",{parentName:"li"},"celery beat")," pod running. If you're using the chart included in the GitHub repository under ",(0,a.kt)("a",{parentName:"li",href:"https://github.com/apache/superset/tree/master/helm/superset"},"helm/superset"),", you need to put ",(0,a.kt)("inlineCode",{parentName:"li"},"supersetCeleryBeat.enabled = true")," in your values override."),(0,a.kt)("li",{parentName:"ul"},"You can see the dedicated docs about ",(0,a.kt)("a",{parentName:"li",href:"/docs/installation/running-on-kubernetes"},"Kubernetes installation")," for more generic details.")),(0,a.kt)("h4",{id:"docker-compose-specific"},"Docker Compose specific"),(0,a.kt)("h5",{id:"you-must-have-in-your-docker-composeyml"},"You must have in your ",(0,a.kt)("inlineCode",{parentName:"h5"},"docker-compose.yml")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"A Redis message broker"),(0,a.kt)("li",{parentName:"ul"},"PostgreSQL DB instead of SQLlite"),(0,a.kt)("li",{parentName:"ul"},"One or more ",(0,a.kt)("inlineCode",{parentName:"li"},"celery worker")),(0,a.kt)("li",{parentName:"ul"},"A single ",(0,a.kt)("inlineCode",{parentName:"li"},"celery beat"))),(0,a.kt)("p",null,"This process also works in a Docker swarm environment, you would just need to add ",(0,a.kt)("inlineCode",{parentName:"p"},"Deploy:")," to the Superset, Redis and Postgres services along with your specific configs for your swarm."),(0,a.kt)("h3",{id:"detailed-config"},"Detailed config"),(0,a.kt)("p",null,"The following configurations need to be added to the ",(0,a.kt)("inlineCode",{parentName:"p"},"superset_config.py")," file. This file is loaded when the image runs, and any configurations in it will override the default configurations found in the ",(0,a.kt)("inlineCode",{parentName:"p"},"config.py"),"."),(0,a.kt)("p",null,"You can find documentation about each field in the default ",(0,a.kt)("inlineCode",{parentName:"p"},"config.py")," in the GitHub repository under ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/apache/superset/blob/master/superset/config.py"},"superset/config.py"),"."),(0,a.kt)("p",null,"You need to replace default values with your custom Redis, Slack and/or SMTP config."),(0,a.kt)("p",null,"Superset uses Celery beat and Celery worker(s) to send alerts and reports."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"The beat is the scheduler that tells the worker when to perform its tasks. This schedule is defined when you create the alert or report."),(0,a.kt)("li",{parentName:"ul"},"The worker will process the  tasks that need to be performed when an alert or report is fired.")),(0,a.kt)("p",null,"In the ",(0,a.kt)("inlineCode",{parentName:"p"},"CeleryConfig"),", only the ",(0,a.kt)("inlineCode",{parentName:"p"},"beat_schedule")," is relevant to this feature, the rest of the ",(0,a.kt)("inlineCode",{parentName:"p"},"CeleryConfig")," can be changed for your needs."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'from celery.schedules import crontab\n\nFEATURE_FLAGS = {\n    "ALERT_REPORTS": True\n}\n\nREDIS_HOST = "superset_cache"\nREDIS_PORT = "6379"\n\nclass CeleryConfig:\n    broker_url = f"redis://{REDIS_HOST}:{REDIS_PORT}/0"\n    imports = (\n        "superset.sql_lab",\n        "superset.tasks.scheduler",\n    )\n    result_backend = f"redis://{REDIS_HOST}:{REDIS_PORT}/0"\n    worker_prefetch_multiplier = 10\n    task_acks_late = True\n    task_annotations = {\n        "sql_lab.get_sql_results": {\n            "rate_limit": "100/s",\n        },\n    }\n    beat_schedule = {\n        "reports.scheduler": {\n            "task": "reports.scheduler",\n            "schedule": crontab(minute="*", hour="*"),\n        },\n        "reports.prune_log": {\n            "task": "reports.prune_log",\n            "schedule": crontab(minute=0, hour=0),\n        },\n    }\nCELERY_CONFIG = CeleryConfig\n\nSCREENSHOT_LOCATE_WAIT = 100\nSCREENSHOT_LOAD_WAIT = 600\n\n# Slack configuration\nSLACK_API_TOKEN = "xoxb-"\n\n# Email configuration\nSMTP_HOST = "smtp.sendgrid.net" # change to your host\nSMTP_PORT = 2525 # your port, e.g. 587\nSMTP_STARTTLS = True\nSMTP_SSL_SERVER_AUTH = True # If your using an SMTP server with a valid certificate\nSMTP_SSL = False\nSMTP_USER = "your_user" # use the empty string "" if using an unauthenticated SMTP server\nSMTP_PASSWORD = "your_password" # use the empty string "" if using an unauthenticated SMTP server\nSMTP_MAIL_FROM = "noreply@youremail.com"\nEMAIL_REPORTS_SUBJECT_PREFIX = "[Superset] " # optional - overwrites default value in config.py of "[Report] "\n\n# WebDriver configuration\n# If you use Firefox, you can stick with default values\n# If you use Chrome, then add the following WEBDRIVER_TYPE and WEBDRIVER_OPTION_ARGS\nWEBDRIVER_TYPE = "chrome"\nWEBDRIVER_OPTION_ARGS = [\n    "--force-device-scale-factor=2.0",\n    "--high-dpi-support=2.0",\n    "--headless",\n    "--disable-gpu",\n    "--disable-dev-shm-usage",\n    "--no-sandbox",\n    "--disable-setuid-sandbox",\n    "--disable-extensions",\n]\n\n# This is for internal use, you can keep http\nWEBDRIVER_BASEURL = "http://superset:8088"\n# This is the link sent to the recipient. Change to your domain, e.g. https://superset.mydomain.com\nWEBDRIVER_BASEURL_USER_FRIENDLY = "http://localhost:8088"\n')),(0,a.kt)("p",null,"You also need\nto specify on behalf of which username to render the dashboards. In general dashboards and charts\nare not accessible to unauthorized requests, that is why the worker needs to take over credentials\nof an existing user to take a snapshot."),(0,a.kt)("p",null,"By default, Alerts and Reports are executed as the owner of the alert/report object. To use a fixed user account,\njust change the config as follows (",(0,a.kt)("inlineCode",{parentName:"p"},"admin")," in this example):"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},"from superset.tasks.types import ExecutorType\n\nTHUMBNAIL_SELENIUM_USER = 'admin'\nALERT_REPORTS_EXECUTE_AS = [ExecutorType.SELENIUM]\n")),(0,a.kt)("p",null,"Please refer to ",(0,a.kt)("inlineCode",{parentName:"p"},"ExecutorType")," in the codebase for other executor types."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Important notes")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Be mindful of the concurrency setting for celery (using ",(0,a.kt)("inlineCode",{parentName:"li"},"-c 4"),"). Selenium/webdriver instances can\nconsume a lot of CPU / memory on your servers."),(0,a.kt)("li",{parentName:"ul"},"In some cases, if you notice a lot of leaked geckodriver processes, try running your celery\nprocesses with ",(0,a.kt)("inlineCode",{parentName:"li"},"celery worker --pool=prefork --max-tasks-per-child=128 ...")),(0,a.kt)("li",{parentName:"ul"},"It is recommended to run separate workers for the ",(0,a.kt)("inlineCode",{parentName:"li"},"sql_lab")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"email_reports")," tasks. This can be\ndone using the ",(0,a.kt)("inlineCode",{parentName:"li"},"queue")," field in ",(0,a.kt)("inlineCode",{parentName:"li"},"task_annotations"),"."),(0,a.kt)("li",{parentName:"ul"},"Adjust ",(0,a.kt)("inlineCode",{parentName:"li"},"WEBDRIVER_BASEURL")," in your configuration file if celery workers can\u2019t access Superset via\nits default value of ",(0,a.kt)("inlineCode",{parentName:"li"},"http://0.0.0.0:8080/"),".")),(0,a.kt)("h3",{id:"custom-dockerfile"},"Custom Dockerfile"),(0,a.kt)("p",null,"If you're running the dev version of a released Superset image, like ",(0,a.kt)("inlineCode",{parentName:"p"},"apache/superset:2.0.1-dev"),", you should be set with the above."),(0,a.kt)("p",null,"But if you're building your own image, or starting with a non-dev version, a webdriver (and headless browser) is needed to capture screenshots of the charts and dashboards which are then sent to the recipient.\nHere's how you can modify your Dockerfile to take the screenshots either with Firefox or Chrome."),(0,a.kt)("h4",{id:"using-firefox"},"Using Firefox"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-docker"},"FROM apache/superset:2.0.1\n\nUSER root\n\nRUN apt-get update && \\\n    apt-get install --no-install-recommends -y firefox-esr\n\nENV GECKODRIVER_VERSION=0.29.0\nRUN wget -q https://github.com/mozilla/geckodriver/releases/download/v${GECKODRIVER_VERSION}/geckodriver-v${GECKODRIVER_VERSION}-linux64.tar.gz && \\\n    tar -x geckodriver -zf geckodriver-v${GECKODRIVER_VERSION}-linux64.tar.gz -O > /usr/bin/geckodriver && \\\n    chmod 755 /usr/bin/geckodriver && \\\n    rm geckodriver-v${GECKODRIVER_VERSION}-linux64.tar.gz\n\nRUN pip install --no-cache gevent psycopg2 redis\n\nUSER superset\n")),(0,a.kt)("h4",{id:"using-chrome"},"Using Chrome"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-docker"},"FROM apache/superset:2.0.1\n\nUSER root\n\nRUN apt-get update && \\\n    wget -q https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb && \\\n    apt-get install -y --no-install-recommends ./google-chrome-stable_current_amd64.deb && \\\n    rm -f google-chrome-stable_current_amd64.deb\n\nRUN export CHROMEDRIVER_VERSION=$(curl --silent https://chromedriver.storage.googleapis.com/LATEST_RELEASE_102) && \\\n    wget -q https://chromedriver.storage.googleapis.com/${CHROMEDRIVER_VERSION}/chromedriver_linux64.zip && \\\n    unzip chromedriver_linux64.zip -d /usr/bin && \\\n    chmod 755 /usr/bin/chromedriver && \\\n    rm -f chromedriver_linux64.zip\n\nRUN pip install --no-cache gevent psycopg2 redis\n\nUSER superset\n")),(0,a.kt)("p",null,"Don't forget to set ",(0,a.kt)("inlineCode",{parentName:"p"},"WEBDRIVER_TYPE")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"WEBDRIVER_OPTION_ARGS")," in your config if you use Chrome."),(0,a.kt)("h3",{id:"schedule-reports"},"Schedule Reports"),(0,a.kt)("p",null,"You can optionally allow your users to schedule queries directly in SQL Lab. This is done by adding\nextra metadata to saved queries, which are then picked up by an external scheduled (like\n",(0,a.kt)("a",{parentName:"p",href:"https://airflow.apache.org/"},"Apache Airflow"),")."),(0,a.kt)("p",null,"To allow scheduled queries, add the following to ",(0,a.kt)("inlineCode",{parentName:"p"},"SCHEDULED_QUERIES")," in your configuration file:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},"SCHEDULED_QUERIES = {\n    # This information is collected when the user clicks \"Schedule query\",\n    # and saved into the `extra` field of saved queries.\n    # See: https://github.com/mozilla-services/react-jsonschema-form\n    'JSONSCHEMA': {\n        'title': 'Schedule',\n        'description': (\n            'In order to schedule a query, you need to specify when it '\n            'should start running, when it should stop running, and how '\n            'often it should run. You can also optionally specify '\n            'dependencies that should be met before the query is '\n            'executed. Please read the documentation for best practices '\n            'and more information on how to specify dependencies.'\n        ),\n        'type': 'object',\n        'properties': {\n            'output_table': {\n                'type': 'string',\n                'title': 'Output table name',\n            },\n            'start_date': {\n                'type': 'string',\n                'title': 'Start date',\n                # date-time is parsed using the chrono library, see\n                # https://www.npmjs.com/package/chrono-node#usage\n                'format': 'date-time',\n                'default': 'tomorrow at 9am',\n            },\n            'end_date': {\n                'type': 'string',\n                'title': 'End date',\n                # date-time is parsed using the chrono library, see\n                # https://www.npmjs.com/package/chrono-node#usage\n                'format': 'date-time',\n                'default': '9am in 30 days',\n            },\n            'schedule_interval': {\n                'type': 'string',\n                'title': 'Schedule interval',\n            },\n            'dependencies': {\n                'type': 'array',\n                'title': 'Dependencies',\n                'items': {\n                    'type': 'string',\n                },\n            },\n        },\n    },\n    'UISCHEMA': {\n        'schedule_interval': {\n            'ui:placeholder': '@daily, @weekly, etc.',\n        },\n        'dependencies': {\n            'ui:help': (\n                'Check the documentation for the correct format when '\n                'defining dependencies.'\n            ),\n        },\n    },\n    'VALIDATION': [\n        # ensure that start_date <= end_date\n        {\n            'name': 'less_equal',\n            'arguments': ['start_date', 'end_date'],\n            'message': 'End date cannot be before start date',\n            # this is where the error message is shown\n            'container': 'end_date',\n        },\n    ],\n    # link to the scheduler; this example links to an Airflow pipeline\n    # that uses the query id and the output table as its name\n    'linkback': (\n        'https://airflow.example.com/admin/airflow/tree?'\n        'dag_id=query_${id}_${extra_json.schedule_info.output_table}'\n    ),\n}\n")),(0,a.kt)("p",null,"This configuration is based on\n",(0,a.kt)("a",{parentName:"p",href:"https://github.com/mozilla-services/react-jsonschema-form"},"react-jsonschema-form")," and will add a\nmenu item called \u201cSchedule\u201d to SQL Lab. When the menu item is clicked, a modal will show up where\nthe user can add the metadata required for scheduling the query."),(0,a.kt)("p",null,"This information can then be retrieved from the endpoint ",(0,a.kt)("inlineCode",{parentName:"p"},"/savedqueryviewapi/api/read")," and used to\nschedule the queries that have ",(0,a.kt)("inlineCode",{parentName:"p"},"scheduled_queries")," in their JSON metadata. For schedulers other than\nAirflow, additional fields can be easily added to the configuration file above."))}c.isMDXComponent=!0},3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},o=Object.keys(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),u=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d=function(e){var t=u(e.components);return r.createElement(l.Provider,{value:t},e.children)},p="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=u(n),h=a,m=p["".concat(l,".").concat(h)]||p[h]||c[h]||o;return n?r.createElement(m,i(i({ref:t},d),{},{components:n})):r.createElement(m,i({ref:t},d))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:a,i[1]=s;for(var u=2;u<o;u++)i[u]=n[u];return r.createElement.apply(null,i)}return r.createElement.apply(null,n)}h.displayName="MDXCreateElement"}}]);
\ No newline at end of file
diff --git a/assets/js/f9cc156b.ea4252e6.js b/assets/js/f9cc156b.ea4252e6.js
deleted file mode 100644
index cd04dd8..0000000
--- a/assets/js/f9cc156b.ea4252e6.js
+++ /dev/null
@@ -1 +0,0 @@
-"use strict";(self.webpackChunkdocs_v_2=self.webpackChunkdocs_v_2||[]).push([[8915],{6974:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>c,frontMatter:()=>o,metadata:()=>s,toc:()=>u});var r=n(83117),a=(n(67294),n(3905));const o={title:"Alerts and Reports",hide_title:!0,sidebar_position:10,version:2},i=void 0,s={unversionedId:"installation/alerts-reports",id:"installation/alerts-reports",title:"Alerts and Reports",description:"Alerts and Reports",source:"@site/docs/installation/alerts-reports.mdx",sourceDirName:"installation",slug:"/installation/alerts-reports",permalink:"/docs/installation/alerts-reports",draft:!1,editUrl:"https://github.com/apache/superset/tree/master/docs/docs/installation/alerts-reports.mdx",tags:[],version:"current",sidebarPosition:10,frontMatter:{title:"Alerts and Reports",hide_title:!0,sidebar_position:10,version:2},sidebar:"tutorialSidebar",previous:{title:"Async Queries via Celery",permalink:"/docs/installation/async-queries-celery"},next:{title:"SQL Templating",permalink:"/docs/installation/sql-templating"}},l={},u=[{value:"Alerts and Reports",id:"alerts-and-reports",level:2},{value:"Requirements",id:"requirements",level:3},{value:"Commons",id:"commons",level:4},{value:"In your <code>superset_config.py</code> or <code>superset_config_docker.py</code>",id:"in-your-superset_configpy-or-superset_config_dockerpy",level:5},{value:"Disable dry-run mode",id:"disable-dry-run-mode",level:6},{value:"In your <code>Dockerfile</code>",id:"in-your-dockerfile",level:5},{value:"Slack integration",id:"slack-integration",level:4},{value:"Kubernetes-specific",id:"kubernetes-specific",level:4},{value:"Docker Compose specific",id:"docker-compose-specific",level:4},{value:"You must have in your <code>docker-compose.yml</code>",id:"you-must-have-in-your-docker-composeyml",level:5},{value:"Detailed config",id:"detailed-config",level:3},{value:"Custom Dockerfile",id:"custom-dockerfile",level:3},{value:"Using Firefox",id:"using-firefox",level:4},{value:"Using Chrome",id:"using-chrome",level:4},{value:"Schedule Reports",id:"schedule-reports",level:3}],d={toc:u},p="wrapper";function c(e){let{components:t,...n}=e;return(0,a.kt)(p,(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h2",{id:"alerts-and-reports"},"Alerts and Reports"),(0,a.kt)("p",null,(0,a.kt)("em",{parentName:"p"},"This covers versions 1.0.1 to current.")),(0,a.kt)("p",null,"Users can configure automated alerts and reports to send dashboards or charts to an email recipient or Slack channel."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Alerts are sent when a SQL condition is reached"),(0,a.kt)("li",{parentName:"ul"},"Reports are sent on a schedule")),(0,a.kt)("p",null,"Alerts and reports are disabled by default. To turn them on, you need to do some setup, described here."),(0,a.kt)("h3",{id:"requirements"},"Requirements"),(0,a.kt)("h4",{id:"commons"},"Commons"),(0,a.kt)("h5",{id:"in-your-superset_configpy-or-superset_config_dockerpy"},"In your ",(0,a.kt)("inlineCode",{parentName:"h5"},"superset_config.py")," or ",(0,a.kt)("inlineCode",{parentName:"h5"},"superset_config_docker.py")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},'"ALERT_REPORTS"')," ",(0,a.kt)("a",{parentName:"li",href:"https://superset.apache.org/docs/installation/configuring-superset#feature-flags"},"feature flag")," must be turned to True."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"beat_schedule")," in CeleryConfig must contain schedule for ",(0,a.kt)("inlineCode",{parentName:"li"},"reports.scheduler"),"."),(0,a.kt)("li",{parentName:"ul"},"At least one of those must be configured, depending on what you want to use:",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"emails: ",(0,a.kt)("inlineCode",{parentName:"li"},"SMTP_*")," settings"),(0,a.kt)("li",{parentName:"ul"},"Slack messages: ",(0,a.kt)("inlineCode",{parentName:"li"},"SLACK_API_TOKEN"))))),(0,a.kt)("h6",{id:"disable-dry-run-mode"},"Disable dry-run mode"),(0,a.kt)("p",null,"Screenshots will be taken but no messages actually sent as long as ",(0,a.kt)("inlineCode",{parentName:"p"},"ALERT_REPORTS_NOTIFICATION_DRY_RUN = True"),", its default value in ",(0,a.kt)("inlineCode",{parentName:"p"},"docker/pythonpath_dev/superset_config.py"),".  To disable dry-run mode and start receiving email/Slack notifications, set ",(0,a.kt)("inlineCode",{parentName:"p"},"ALERT_REPORTS_NOTIFICATION_DRY_RUN")," to ",(0,a.kt)("inlineCode",{parentName:"p"},"False")," in ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/apache/superset/blob/master/docker/pythonpath_dev/superset_config.py"},"superset config"),"."),(0,a.kt)("h5",{id:"in-your-dockerfile"},"In your ",(0,a.kt)("inlineCode",{parentName:"h5"},"Dockerfile")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"You must install a headless browser, for taking screenshots of the charts and dashboards. Only Firefox and Chrome are currently supported.",(0,a.kt)("blockquote",{parentName:"li"},(0,a.kt)("p",{parentName:"blockquote"},"If you choose Chrome, you must also change the value of ",(0,a.kt)("inlineCode",{parentName:"p"},"WEBDRIVER_TYPE")," to ",(0,a.kt)("inlineCode",{parentName:"p"},'"chrome"')," in your ",(0,a.kt)("inlineCode",{parentName:"p"},"superset_config.py"),".")))),(0,a.kt)("p",null,"Note: All the components required (Firefox headless browser, Redis, Postgres db, celery worker and celery beat) are present in the ",(0,a.kt)("em",{parentName:"p"},"dev")," docker image if you are following ",(0,a.kt)("a",{parentName:"p",href:"https://superset.apache.org/docs/installation/installing-superset-using-docker-compose/"},"Installing Superset Locally"),".\nAll you need to do is add the required config variables described in this guide (See ",(0,a.kt)("inlineCode",{parentName:"p"},"Detailed Config"),")."),(0,a.kt)("p",null,"If you are running a non-dev docker image, e.g., a stable release like ",(0,a.kt)("inlineCode",{parentName:"p"},"apache/superset:2.0.1"),", that image does not include a headless browser.  Only the ",(0,a.kt)("inlineCode",{parentName:"p"},"superset_worker"),' container needs this headless browser to browse to the target chart or dashboard.\nYou can either install and configure the headless browser - see "Custom Dockerfile" section below - or when deploying via ',(0,a.kt)("inlineCode",{parentName:"p"},"docker compose"),", modify your ",(0,a.kt)("inlineCode",{parentName:"p"},"docker-compose.yml")," file to use a dev image for the worker container and a stable release image for the ",(0,a.kt)("inlineCode",{parentName:"p"},"superset_app")," container."),(0,a.kt)("p",null,(0,a.kt)("em",{parentName:"p"},"Note"),': In this context, a "dev image" is the same application software as its corresponding non-dev image, just bundled with additional tools.  So an image like ',(0,a.kt)("inlineCode",{parentName:"p"},"2.0.1-dev")," is identical to ",(0,a.kt)("inlineCode",{parentName:"p"},"2.0.1"),' when it comes to stability, functionality, and running in production.  The actual "in-development" versions of Superset - cutting-edge and unstable - are not tagged with version numbers on Docker Hub and will display version ',(0,a.kt)("inlineCode",{parentName:"p"},"0.0.0-dev")," within the Superset UI."),(0,a.kt)("h4",{id:"slack-integration"},"Slack integration"),(0,a.kt)("p",null,"To send alerts and reports to Slack channels, you need to create a new Slack Application on your workspace."),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Connect to your Slack workspace, then head to ",(0,a.kt)("a",{parentName:"li",href:"https://api.slack.com/apps"},"https://api.slack.com/apps"),"."),(0,a.kt)("li",{parentName:"ol"},"Create a new app."),(0,a.kt)("li",{parentName:"ol"},'Go to "OAuth & Permissions" section, and give the following scopes to your app:',(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"incoming-webhook")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"files:write")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"chat:write")))),(0,a.kt)("li",{parentName:"ol"},'At the top of the "OAuth and Permissions" section, click "install to workspace".'),(0,a.kt)("li",{parentName:"ol"},"Select a default channel for your app and continue.\n(You can post to any channel by inviting your Superset app into that channel)."),(0,a.kt)("li",{parentName:"ol"},'The app should now be installed in your workspace, and a "Bot User OAuth Access Token" should have been created. Copy that token in the ',(0,a.kt)("inlineCode",{parentName:"li"},"SLACK_API_TOKEN")," variable of your ",(0,a.kt)("inlineCode",{parentName:"li"},"superset_config.py"),"."),(0,a.kt)("li",{parentName:"ol"},"Restart the service (or run ",(0,a.kt)("inlineCode",{parentName:"li"},"superset init"),") to pull in the new configuration.")),(0,a.kt)("p",null,"Note: when you configure an alert or a report, the Slack channel list takes channel names without the leading '#' e.g. use ",(0,a.kt)("inlineCode",{parentName:"p"},"alerts")," instead of ",(0,a.kt)("inlineCode",{parentName:"p"},"#alerts"),"."),(0,a.kt)("h4",{id:"kubernetes-specific"},"Kubernetes-specific"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"You must have a ",(0,a.kt)("inlineCode",{parentName:"li"},"celery beat")," pod running. If you're using the chart included in the GitHub repository under ",(0,a.kt)("a",{parentName:"li",href:"https://github.com/apache/superset/tree/master/helm/superset"},"helm/superset"),", you need to put ",(0,a.kt)("inlineCode",{parentName:"li"},"supersetCeleryBeat.enabled = true")," in your values override."),(0,a.kt)("li",{parentName:"ul"},"You can see the dedicated docs about ",(0,a.kt)("a",{parentName:"li",href:"/docs/installation/running-on-kubernetes"},"Kubernetes installation")," for more generic details.")),(0,a.kt)("h4",{id:"docker-compose-specific"},"Docker Compose specific"),(0,a.kt)("h5",{id:"you-must-have-in-your-docker-composeyml"},"You must have in your ",(0,a.kt)("inlineCode",{parentName:"h5"},"docker-compose.yml")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"A Redis message broker"),(0,a.kt)("li",{parentName:"ul"},"PostgreSQL DB instead of SQLlite"),(0,a.kt)("li",{parentName:"ul"},"One or more ",(0,a.kt)("inlineCode",{parentName:"li"},"celery worker")),(0,a.kt)("li",{parentName:"ul"},"A single ",(0,a.kt)("inlineCode",{parentName:"li"},"celery beat"))),(0,a.kt)("p",null,"This process also works in a Docker swarm environment, you would just need to add ",(0,a.kt)("inlineCode",{parentName:"p"},"Deploy:")," to the Superset, Redis and Postgres services along with your specific configs for your swarm."),(0,a.kt)("h3",{id:"detailed-config"},"Detailed config"),(0,a.kt)("p",null,"The following configurations need to be added to the ",(0,a.kt)("inlineCode",{parentName:"p"},"superset_config.py")," file. This file is loaded when the image runs, and any configurations in it will override the default configurations found in the ",(0,a.kt)("inlineCode",{parentName:"p"},"config.py"),"."),(0,a.kt)("p",null,"You can find documentation about each field in the default ",(0,a.kt)("inlineCode",{parentName:"p"},"config.py")," in the GitHub repository under ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/apache/superset/blob/master/superset/config.py"},"superset/config.py"),"."),(0,a.kt)("p",null,"You need to replace default values with your custom Redis, Slack and/or SMTP config."),(0,a.kt)("p",null,"Superset uses Celery beat and Celery worker(s) to send alerts and reports."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"The beat is the scheduler that tells the worker when to perform its tasks. This schedule is defined when you create the alert or report."),(0,a.kt)("li",{parentName:"ul"},"The worker will process the  tasks that need to be performed when an alert or report is fired.")),(0,a.kt)("p",null,"In the ",(0,a.kt)("inlineCode",{parentName:"p"},"CeleryConfig"),", only the ",(0,a.kt)("inlineCode",{parentName:"p"},"beat_schedule")," is relevant to this feature, the rest of the ",(0,a.kt)("inlineCode",{parentName:"p"},"CeleryConfig")," can be changed for your needs."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},'from celery.schedules import crontab\n\nFEATURE_FLAGS = {\n    "ALERT_REPORTS": True\n}\n\nREDIS_HOST = "superset_cache"\nREDIS_PORT = "6379"\n\nclass CeleryConfig:\n    broker_url = \'redis://%s:%s/0\' % (REDIS_HOST, REDIS_PORT)\n    imports = (\'superset.sql_lab\', "superset.tasks", "superset.tasks.thumbnails", )\n    result_backend = \'redis://%s:%s/0\' % (REDIS_HOST, REDIS_PORT)\n    worker_prefetch_multiplier = 10\n    task_acks_late = True\n    task_annotations = {\n        \'sql_lab.get_sql_results\': {\n            \'rate_limit\': \'100/s\',\n        },\n        \'email_reports.send\': {\n            \'rate_limit\': \'1/s\',\n            \'time_limit\': 600,\n            \'soft_time_limit\': 600,\n            \'ignore_result\': True,\n        },\n    }\n    beat_schedule = {\n        \'reports.scheduler\': {\n            \'task\': \'reports.scheduler\',\n            \'schedule\': crontab(minute=\'*\', hour=\'*\'),\n        },\n        \'reports.prune_log\': {\n            \'task\': \'reports.prune_log\',\n            \'schedule\': crontab(minute=0, hour=0),\n        },\n    }\nCELERY_CONFIG = CeleryConfig\n\nSCREENSHOT_LOCATE_WAIT = 100\nSCREENSHOT_LOAD_WAIT = 600\n\n# Slack configuration\nSLACK_API_TOKEN = "xoxb-"\n\n# Email configuration\nSMTP_HOST = "smtp.sendgrid.net" # change to your host\nSMTP_PORT = 2525 # your port, e.g. 587\nSMTP_STARTTLS = True\nSMTP_SSL_SERVER_AUTH = True # If your using an SMTP server with a valid certificate\nSMTP_SSL = False\nSMTP_USER = "your_user" # use the empty string "" if using an unauthenticated SMTP server\nSMTP_PASSWORD = "your_password" # use the empty string "" if using an unauthenticated SMTP server\nSMTP_MAIL_FROM = "noreply@youremail.com"\nEMAIL_REPORTS_SUBJECT_PREFIX = "[Superset] " # optional - overwrites default value in config.py of "[Report] "\n\n# WebDriver configuration\n# If you use Firefox, you can stick with default values\n# If you use Chrome, then add the following WEBDRIVER_TYPE and WEBDRIVER_OPTION_ARGS\nWEBDRIVER_TYPE = "chrome"\nWEBDRIVER_OPTION_ARGS = [\n    "--force-device-scale-factor=2.0",\n    "--high-dpi-support=2.0",\n    "--headless",\n    "--disable-gpu",\n    "--disable-dev-shm-usage",\n    "--no-sandbox",\n    "--disable-setuid-sandbox",\n    "--disable-extensions",\n]\n\n# This is for internal use, you can keep http\nWEBDRIVER_BASEURL = "http://superset:8088"\n# This is the link sent to the recipient. Change to your domain, e.g. https://superset.mydomain.com\nWEBDRIVER_BASEURL_USER_FRIENDLY = "http://localhost:8088"\n')),(0,a.kt)("p",null,"You also need\nto specify on behalf of which username to render the dashboards. In general dashboards and charts\nare not accessible to unauthorized requests, that is why the worker needs to take over credentials\nof an existing user to take a snapshot."),(0,a.kt)("p",null,"By default, Alerts and Reports are executed as the owner of the alert/report object. To use a fixed user account,\njust change the config as follows (",(0,a.kt)("inlineCode",{parentName:"p"},"admin")," in this example):"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},"from superset.tasks.types import ExecutorType\n\nTHUMBNAIL_SELENIUM_USER = 'admin'\nALERT_REPORTS_EXECUTE_AS = [ExecutorType.SELENIUM]\n")),(0,a.kt)("p",null,"Please refer to ",(0,a.kt)("inlineCode",{parentName:"p"},"ExecutorType")," in the codebase for other executor types."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Important notes")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Be mindful of the concurrency setting for celery (using ",(0,a.kt)("inlineCode",{parentName:"li"},"-c 4"),"). Selenium/webdriver instances can\nconsume a lot of CPU / memory on your servers."),(0,a.kt)("li",{parentName:"ul"},"In some cases, if you notice a lot of leaked geckodriver processes, try running your celery\nprocesses with ",(0,a.kt)("inlineCode",{parentName:"li"},"celery worker --pool=prefork --max-tasks-per-child=128 ...")),(0,a.kt)("li",{parentName:"ul"},"It is recommended to run separate workers for the ",(0,a.kt)("inlineCode",{parentName:"li"},"sql_lab")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"email_reports")," tasks. This can be\ndone using the ",(0,a.kt)("inlineCode",{parentName:"li"},"queue")," field in ",(0,a.kt)("inlineCode",{parentName:"li"},"task_annotations"),"."),(0,a.kt)("li",{parentName:"ul"},"Adjust ",(0,a.kt)("inlineCode",{parentName:"li"},"WEBDRIVER_BASEURL")," in your configuration file if celery workers can\u2019t access Superset via\nits default value of ",(0,a.kt)("inlineCode",{parentName:"li"},"http://0.0.0.0:8080/"),".")),(0,a.kt)("h3",{id:"custom-dockerfile"},"Custom Dockerfile"),(0,a.kt)("p",null,"If you're running the dev version of a released Superset image, like ",(0,a.kt)("inlineCode",{parentName:"p"},"apache/superset:2.0.1-dev"),", you should be set with the above."),(0,a.kt)("p",null,"But if you're building your own image, or starting with a non-dev version, a webdriver (and headless browser) is needed to capture screenshots of the charts and dashboards which are then sent to the recipient.\nHere's how you can modify your Dockerfile to take the screenshots either with Firefox or Chrome."),(0,a.kt)("h4",{id:"using-firefox"},"Using Firefox"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-docker"},"FROM apache/superset:2.0.1\n\nUSER root\n\nRUN apt-get update && \\\n    apt-get install --no-install-recommends -y firefox-esr\n\nENV GECKODRIVER_VERSION=0.29.0\nRUN wget -q https://github.com/mozilla/geckodriver/releases/download/v${GECKODRIVER_VERSION}/geckodriver-v${GECKODRIVER_VERSION}-linux64.tar.gz && \\\n    tar -x geckodriver -zf geckodriver-v${GECKODRIVER_VERSION}-linux64.tar.gz -O > /usr/bin/geckodriver && \\\n    chmod 755 /usr/bin/geckodriver && \\\n    rm geckodriver-v${GECKODRIVER_VERSION}-linux64.tar.gz\n\nRUN pip install --no-cache gevent psycopg2 redis\n\nUSER superset\n")),(0,a.kt)("h4",{id:"using-chrome"},"Using Chrome"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-docker"},"FROM apache/superset:2.0.1\n\nUSER root\n\nRUN apt-get update && \\\n    wget -q https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb && \\\n    apt-get install -y --no-install-recommends ./google-chrome-stable_current_amd64.deb && \\\n    rm -f google-chrome-stable_current_amd64.deb\n\nRUN export CHROMEDRIVER_VERSION=$(curl --silent https://chromedriver.storage.googleapis.com/LATEST_RELEASE_102) && \\\n    wget -q https://chromedriver.storage.googleapis.com/${CHROMEDRIVER_VERSION}/chromedriver_linux64.zip && \\\n    unzip chromedriver_linux64.zip -d /usr/bin && \\\n    chmod 755 /usr/bin/chromedriver && \\\n    rm -f chromedriver_linux64.zip\n\nRUN pip install --no-cache gevent psycopg2 redis\n\nUSER superset\n")),(0,a.kt)("p",null,"Don't forget to set ",(0,a.kt)("inlineCode",{parentName:"p"},"WEBDRIVER_TYPE")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"WEBDRIVER_OPTION_ARGS")," in your config if you use Chrome."),(0,a.kt)("h3",{id:"schedule-reports"},"Schedule Reports"),(0,a.kt)("p",null,"You can optionally allow your users to schedule queries directly in SQL Lab. This is done by adding\nextra metadata to saved queries, which are then picked up by an external scheduled (like\n",(0,a.kt)("a",{parentName:"p",href:"https://airflow.apache.org/"},"Apache Airflow"),")."),(0,a.kt)("p",null,"To allow scheduled queries, add the following to ",(0,a.kt)("inlineCode",{parentName:"p"},"SCHEDULED_QUERIES")," in your configuration file:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-python"},"SCHEDULED_QUERIES = {\n    # This information is collected when the user clicks \"Schedule query\",\n    # and saved into the `extra` field of saved queries.\n    # See: https://github.com/mozilla-services/react-jsonschema-form\n    'JSONSCHEMA': {\n        'title': 'Schedule',\n        'description': (\n            'In order to schedule a query, you need to specify when it '\n            'should start running, when it should stop running, and how '\n            'often it should run. You can also optionally specify '\n            'dependencies that should be met before the query is '\n            'executed. Please read the documentation for best practices '\n            'and more information on how to specify dependencies.'\n        ),\n        'type': 'object',\n        'properties': {\n            'output_table': {\n                'type': 'string',\n                'title': 'Output table name',\n            },\n            'start_date': {\n                'type': 'string',\n                'title': 'Start date',\n                # date-time is parsed using the chrono library, see\n                # https://www.npmjs.com/package/chrono-node#usage\n                'format': 'date-time',\n                'default': 'tomorrow at 9am',\n            },\n            'end_date': {\n                'type': 'string',\n                'title': 'End date',\n                # date-time is parsed using the chrono library, see\n                # https://www.npmjs.com/package/chrono-node#usage\n                'format': 'date-time',\n                'default': '9am in 30 days',\n            },\n            'schedule_interval': {\n                'type': 'string',\n                'title': 'Schedule interval',\n            },\n            'dependencies': {\n                'type': 'array',\n                'title': 'Dependencies',\n                'items': {\n                    'type': 'string',\n                },\n            },\n        },\n    },\n    'UISCHEMA': {\n        'schedule_interval': {\n            'ui:placeholder': '@daily, @weekly, etc.',\n        },\n        'dependencies': {\n            'ui:help': (\n                'Check the documentation for the correct format when '\n                'defining dependencies.'\n            ),\n        },\n    },\n    'VALIDATION': [\n        # ensure that start_date <= end_date\n        {\n            'name': 'less_equal',\n            'arguments': ['start_date', 'end_date'],\n            'message': 'End date cannot be before start date',\n            # this is where the error message is shown\n            'container': 'end_date',\n        },\n    ],\n    # link to the scheduler; this example links to an Airflow pipeline\n    # that uses the query id and the output table as its name\n    'linkback': (\n        'https://airflow.example.com/admin/airflow/tree?'\n        'dag_id=query_${id}_${extra_json.schedule_info.output_table}'\n    ),\n}\n")),(0,a.kt)("p",null,"This configuration is based on\n",(0,a.kt)("a",{parentName:"p",href:"https://github.com/mozilla-services/react-jsonschema-form"},"react-jsonschema-form")," and will add a\nmenu item called \u201cSchedule\u201d to SQL Lab. When the menu item is clicked, a modal will show up where\nthe user can add the metadata required for scheduling the query."),(0,a.kt)("p",null,"This information can then be retrieved from the endpoint ",(0,a.kt)("inlineCode",{parentName:"p"},"/savedqueryviewapi/api/read")," and used to\nschedule the queries that have ",(0,a.kt)("inlineCode",{parentName:"p"},"scheduled_queries")," in their JSON metadata. For schedulers other than\nAirflow, additional fields can be easily added to the configuration file above."))}c.isMDXComponent=!0},3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},o=Object.keys(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),u=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d=function(e){var t=u(e.components);return r.createElement(l.Provider,{value:t},e.children)},p="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=u(n),h=a,m=p["".concat(l,".").concat(h)]||p[h]||c[h]||o;return n?r.createElement(m,i(i({ref:t},d),{},{components:n})):r.createElement(m,i({ref:t},d))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:a,i[1]=s;for(var u=2;u<o;u++)i[u]=n[u];return r.createElement.apply(null,i)}return r.createElement.apply(null,n)}h.displayName="MDXCreateElement"}}]);
\ No newline at end of file
diff --git a/assets/js/fe0957ee.f71b66b9.js b/assets/js/fe0957ee.7fb3f346.js
similarity index 77%
rename from assets/js/fe0957ee.f71b66b9.js
rename to assets/js/fe0957ee.7fb3f346.js
index f99ecfd..bea0e78 100644
--- a/assets/js/fe0957ee.f71b66b9.js
+++ b/assets/js/fe0957ee.7fb3f346.js
@@ -1 +1 @@
-"use strict";(self.webpackChunkdocs_v_2=self.webpackChunkdocs_v_2||[]).push([[9822],{25079:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>l,default:()=>c,frontMatter:()=>s,metadata:()=>i,toc:()=>p});var a=n(83117),r=(n(67294),n(3905));const s={title:"Installing on Kubernetes",hide_title:!0,sidebar_position:3,version:1},l=void 0,i={unversionedId:"installation/running-on-kubernetes",id:"installation/running-on-kubernetes",title:"Installing on Kubernetes",description:"Installing on Kubernetes",source:"@site/docs/installation/running-on-kubernetes.mdx",sourceDirName:"installation",slug:"/installation/running-on-kubernetes",permalink:"/docs/installation/running-on-kubernetes",draft:!1,editUrl:"https://github.com/apache/superset/tree/master/docs/docs/installation/running-on-kubernetes.mdx",tags:[],version:"current",sidebarPosition:3,frontMatter:{title:"Installing on Kubernetes",hide_title:!0,sidebar_position:3,version:1},sidebar:"tutorialSidebar",previous:{title:"Installing From Scratch",permalink:"/docs/installation/installing-superset-from-scratch"},next:{title:"Configuring Superset",permalink:"/docs/installation/configuring-superset"}},o={},p=[{value:"Installing on Kubernetes",id:"installing-on-kubernetes",level:2},{value:"Prerequisites",id:"prerequisites",level:3},{value:"Running",id:"running",level:3},{value:"Important settings",id:"important-settings",level:3},{value:"Security settings",id:"security-settings",level:4},{value:"Dependencies",id:"dependencies",level:4},{value:"superset_config.py",id:"superset_configpy",level:4},{value:"Environment Variables",id:"environment-variables",level:4},{value:"System packages",id:"system-packages",level:4},{value:"Data sources",id:"data-sources",level:4},{value:"Configuration Examples",id:"configuration-examples",level:3},{value:"Setting up OAuth",id:"setting-up-oauth",level:4},{value:"Enable Alerts and Reports",id:"enable-alerts-and-reports",level:4},{value:"Install a supported webdriver in the Celery worker",id:"install-a-supported-webdriver-in-the-celery-worker",level:5},{value:"Run the Celery beat",id:"run-the-celery-beat",level:5},{value:"Configure the appropriate Celery jobs and SMTP/Slack settings",id:"configure-the-appropriate-celery-jobs-and-smtpslack-settings",level:5},{value:"Load the Examples data and dashboards",id:"load-the-examples-data-and-dashboards",level:4}],u={toc:p},d="wrapper";function c(e){let{components:t,...n}=e;return(0,r.kt)(d,(0,a.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h2",{id:"installing-on-kubernetes"},"Installing on Kubernetes"),(0,r.kt)("p",null,"Running Superset on Kubernetes is supported with the provided ",(0,r.kt)("a",{parentName:"p",href:"https://helm.sh/"},"Helm")," chart found in the official ",(0,r.kt)("a",{parentName:"p",href:"https://apache.github.io/superset/index.yaml"},"Superset helm repository"),"."),(0,r.kt)("h3",{id:"prerequisites"},"Prerequisites"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"A Kubernetes cluster"),(0,r.kt)("li",{parentName:"ul"},"Helm installed")),(0,r.kt)("h3",{id:"running"},"Running"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Add the Superset helm repository")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},'helm repo add superset https://apache.github.io/superset\n"superset" has been added to your repositories\n')),(0,r.kt)("ol",{start:2},(0,r.kt)("li",{parentName:"ol"},"View charts in repo")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"helm search repo superset\nNAME                    CHART VERSION   APP VERSION     DESCRIPTION\nsuperset/superset       0.1.1           1.0             Apache Superset is a modern, enterprise-ready b...\n")),(0,r.kt)("ol",{start:3},(0,r.kt)("li",{parentName:"ol"},"Configure your setting overrides")),(0,r.kt)("p",null,"Just like any typical Helm chart, you'll need to craft a ",(0,r.kt)("inlineCode",{parentName:"p"},"values.yaml")," file that would define/override any of the values exposed into the default ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/apache/superset/tree/master/helm/superset/values.yaml"},"values.yaml"),", or from any of the dependent charts it depends on:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://artifacthub.io/packages/helm/bitnami/redis"},"bitnami/redis")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://artifacthub.io/packages/helm/bitnami/postgresql"},"bitnami/postgresql"))),(0,r.kt)("p",null,"More info down below on some important overrides you might need."),(0,r.kt)("ol",{start:4},(0,r.kt)("li",{parentName:"ol"},"Install and run")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"helm upgrade --install --values my-values.yaml superset superset/superset\n")),(0,r.kt)("p",null,"You should see various pods popping up, such as:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"kubectl get pods\nNAME                                    READY   STATUS      RESTARTS   AGE\nsuperset-celerybeat-7cdcc9575f-k6xmc    1/1     Running     0          119s\nsuperset-f5c9c667-dw9lp                 1/1     Running     0          4m7s\nsuperset-f5c9c667-fk8bk                 1/1     Running     0          4m11s\nsuperset-init-db-zlm9z                  0/1     Completed   0          111s\nsuperset-postgresql-0                   1/1     Running     0          6d20h\nsuperset-redis-master-0                 1/1     Running     0          6d20h\nsuperset-worker-75b48bbcc-jmmjr         1/1     Running     0          4m8s\nsuperset-worker-75b48bbcc-qrq49         1/1     Running     0          4m12s\n")),(0,r.kt)("p",null,"The exact list will depend on some of your specific configuration overrides but you should generally expect:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"N ",(0,r.kt)("inlineCode",{parentName:"li"},"superset-xxxx-yyyy")," and ",(0,r.kt)("inlineCode",{parentName:"li"},"superset-worker-xxxx-yyyy")," pods (depending on your ",(0,r.kt)("inlineCode",{parentName:"li"},"supersetNode.replicaCount")," and ",(0,r.kt)("inlineCode",{parentName:"li"},"supersetWorker.replicaCount")," values)"),(0,r.kt)("li",{parentName:"ul"},"1 ",(0,r.kt)("inlineCode",{parentName:"li"},"superset-postgresql-0")," depending on your postgres settings"),(0,r.kt)("li",{parentName:"ul"},"1 ",(0,r.kt)("inlineCode",{parentName:"li"},"superset-redis-master-0")," depending on your redis settings"),(0,r.kt)("li",{parentName:"ul"},"1 ",(0,r.kt)("inlineCode",{parentName:"li"},"superset-celerybeat-xxxx-yyyy")," pod if you have ",(0,r.kt)("inlineCode",{parentName:"li"},"supersetCeleryBeat.enabled = true")," in your values overrides")),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Access it")),(0,r.kt)("p",null,"The chart will publish appropriate services to expose the Superset UI internally within your k8s cluster. To access it externally you will have to either:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Configure the Service as a ",(0,r.kt)("inlineCode",{parentName:"li"},"LoadBalancer")," or ",(0,r.kt)("inlineCode",{parentName:"li"},"NodePort")),(0,r.kt)("li",{parentName:"ul"},"Set up an ",(0,r.kt)("inlineCode",{parentName:"li"},"Ingress")," for it - the chart includes a definition, but will need to be tuned to your needs (hostname, tls, annotations etc...)"),(0,r.kt)("li",{parentName:"ul"},"Run ",(0,r.kt)("inlineCode",{parentName:"li"},"kubectl port-forward superset-xxxx-yyyy :8088")," to directly tunnel one pod's port into your localhost")),(0,r.kt)("p",null,"Depending how you configured external access, the URL will vary. Once you've identified the appropriate URL you can log in with:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"user: ",(0,r.kt)("inlineCode",{parentName:"li"},"admin")),(0,r.kt)("li",{parentName:"ul"},"password: ",(0,r.kt)("inlineCode",{parentName:"li"},"admin"))),(0,r.kt)("h3",{id:"important-settings"},"Important settings"),(0,r.kt)("h4",{id:"security-settings"},"Security settings"),(0,r.kt)("p",null,"Default security settings and passwords are included but you ",(0,r.kt)("strong",{parentName:"p"},"SHOULD")," override those with your own, in particular:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"postgresql:\n  postgresqlPassword: superset\n")),(0,r.kt)("p",null,"Make sure, you set a unique strong complex alphanumeric string for your SECRET_KEY and use a tool to help you generate\na sufficiently random sequence."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"To generate a good key you can run, ",(0,r.kt)("inlineCode",{parentName:"li"},"openssl rand -base64 42"))),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"configOverrides:\n  secret: |\n    SECRET_KEY = 'YOUR_OWN_RANDOM_GENERATED_SECRET_KEY'\n")),(0,r.kt)("p",null,"If you want to change the previous secret key then you should rotate the keys.\nDefault secret key for kubernetes deployment is ",(0,r.kt)("inlineCode",{parentName:"p"},"thisISaSECRET_1234")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"configOverrides:\n  my_override: |\n    PREVIOUS_SECRET_KEY = 'YOUR_PREVIOUS_SECRET_KEY'\n    SECRET_KEY = 'YOUR_OWN_RANDOM_GENERATED_SECRET_KEY'\ninit:\n  command:\n    - /bin/sh\n    - -c\n    - |\n      . {{ .Values.configMountPath }}/superset_bootstrap.sh\n      superset re-encrypt-secrets\n      . {{ .Values.configMountPath }}/superset_init.sh\n")),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"Superset uses ",(0,r.kt)("a",{parentName:"p",href:"https://about.scarf.sh/scarf-gateway"},"Scarf Gateway")," to collect telemetry data.  Knowing the installation counts for different Superset versions informs the  project's decisions about patching and long-term support. Scarf purges personally identifiable information (PII) and provides only aggregated statistics."),(0,r.kt)("p",{parentName:"admonition"},"To opt-out of this data collection in your Helm-based installation, edit the ",(0,r.kt)("inlineCode",{parentName:"p"},"repository:")," line in your ",(0,r.kt)("inlineCode",{parentName:"p"},"helm/superset/values.yaml")," file, replacing ",(0,r.kt)("inlineCode",{parentName:"p"},"apachesuperset.docker.scarf.sh/apache/superset")," with ",(0,r.kt)("inlineCode",{parentName:"p"},"apache/superset")," to pull the image directly from Docker Hub.")),(0,r.kt)("h4",{id:"dependencies"},"Dependencies"),(0,r.kt)("p",null,"Install additional packages and do any other bootstrap configuration in the bootstrap script.\nFor production clusters it's recommended to build own image with this step done in CI."),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"Superset requires a Python DB-API database driver and a SQLAlchemy\ndialect to be installed for each datastore you want to connect to."),(0,r.kt)("p",{parentName:"admonition"},"See ",(0,r.kt)("a",{parentName:"p",href:"/docs/databases/installing-database-drivers"},"Install Database Drivers")," for more information.")),(0,r.kt)("p",null,"The following example installs the Big Query and Elasticsearch database drivers so that you can\nconnect to those datasources in your Superset installation:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'bootstrapScript: |\n  #!/bin/bash\n  pip install psycopg2==2.9.6 \\\n    sqlalchemy-bigquery==1.6.1 \\\n    elasticsearch-dbapi==0.2.5 &&\\\n  if [ ! -f ~/bootstrap ]; then echo "Running Superset with uid {{ .Values.runAsUser }}" > ~/bootstrap; fi\n')),(0,r.kt)("h4",{id:"superset_configpy"},"superset_config.py"),(0,r.kt)("p",null,"The default ",(0,r.kt)("inlineCode",{parentName:"p"},"superset_config.py")," is fairly minimal and you will very likely need to extend it. This is done by specifying one or more key/value entries in ",(0,r.kt)("inlineCode",{parentName:"p"},"configOverrides"),", e.g.:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'configOverrides:\n  my_override: |\n    # This will make sure the redirect_uri is properly computed, even with SSL offloading\n    ENABLE_PROXY_FIX = True\n    FEATURE_FLAGS = {\n        "DYNAMIC_PLUGINS": True\n    }\n')),(0,r.kt)("p",null,"Those will be evaluated as Helm templates and therefore will be able to reference other ",(0,r.kt)("inlineCode",{parentName:"p"},"values.yaml")," variables e.g. ",(0,r.kt)("inlineCode",{parentName:"p"},"{{ .Values.ingress.hosts[0] }}")," will resolve to your ingress external domain."),(0,r.kt)("p",null,"The entire ",(0,r.kt)("inlineCode",{parentName:"p"},"superset_config.py")," will be installed as a secret, so it is safe to pass sensitive parameters directly... however it might be more readable to use secret env variables for that."),(0,r.kt)("p",null,"Full python files can be provided by running ",(0,r.kt)("inlineCode",{parentName:"p"},"helm upgrade --install --values my-values.yaml --set-file configOverrides.oauth=set_oauth.py")),(0,r.kt)("h4",{id:"environment-variables"},"Environment Variables"),(0,r.kt)("p",null,"Those can be passed as key/values either with ",(0,r.kt)("inlineCode",{parentName:"p"},"extraEnv")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"extraSecretEnv")," if they're sensitive. They can then be referenced from ",(0,r.kt)("inlineCode",{parentName:"p"},"superset_config.py")," using e.g. ",(0,r.kt)("inlineCode",{parentName:"p"},'os.environ.get("VAR")'),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'extraEnv:\n  SMTP_HOST: smtp.gmail.com\n  SMTP_USER: user@gmail.com\n  SMTP_PORT: "587"\n  SMTP_MAIL_FROM: user@gmail.com\n\nextraSecretEnv:\n  SMTP_PASSWORD: xxxx\n\nconfigOverrides:\n  smtp: |\n    import ast\n    SMTP_HOST = os.getenv("SMTP_HOST","localhost")\n    SMTP_STARTTLS = ast.literal_eval(os.getenv("SMTP_STARTTLS", "True"))\n    SMTP_SSL = ast.literal_eval(os.getenv("SMTP_SSL", "False"))\n    SMTP_USER = os.getenv("SMTP_USER","superset")\n    SMTP_PORT = os.getenv("SMTP_PORT",25)\n    SMTP_PASSWORD = os.getenv("SMTP_PASSWORD","superset")\n')),(0,r.kt)("h4",{id:"system-packages"},"System packages"),(0,r.kt)("p",null,"If new system packages are required, they can be installed before application startup by overriding the container's ",(0,r.kt)("inlineCode",{parentName:"p"},"command"),", e.g.:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"supersetWorker:\n  command:\n    - /bin/sh\n    - -c\n    - |\n      apt update\n      apt install -y somepackage\n      apt autoremove -yqq --purge\n      apt clean\n\n      # Run celery worker\n      . {{ .Values.configMountPath }}/superset_bootstrap.sh; celery --app=superset.tasks.celery_app:app worker\n")),(0,r.kt)("h4",{id:"data-sources"},"Data sources"),(0,r.kt)("p",null,"Data source definitions can be automatically declared by providing key/value yaml definitions in ",(0,r.kt)("inlineCode",{parentName:"p"},"extraConfigs"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'extraConfigs:\n  import_datasources.yaml: |\n    databases:\n    - allow_file_upload: true\n      allow_ctas: true\n      allow_cvas: true\n      database_name: example-db\n      extra: "{\\r\\n    \\"metadata_params\\": {},\\r\\n    \\"engine_params\\": {},\\r\\n    \\"\\\n        metadata_cache_timeout\\": {},\\r\\n    \\"schemas_allowed_for_file_upload\\": []\\r\\n\\\n        }"\n      sqlalchemy_uri: example://example-db.local\n      tables: []\n')),(0,r.kt)("p",null,"Those will also be mounted as secrets and can include sensitive parameters."),(0,r.kt)("h3",{id:"configuration-examples"},"Configuration Examples"),(0,r.kt)("h4",{id:"setting-up-oauth"},"Setting up OAuth"),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"OAuth setup requires that the ",(0,r.kt)("a",{parentName:"p",href:"https://authlib.org/"},"authlib")," Python library is installed. This can\nbe done using ",(0,r.kt)("inlineCode",{parentName:"p"},"pip")," by updating the ",(0,r.kt)("inlineCode",{parentName:"p"},"bootstrapScript"),". See the ",(0,r.kt)("a",{parentName:"p",href:"#dependencies"},"Dependencies")," section\nfor more information.")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'extraEnv:\n  AUTH_DOMAIN: example.com\n\nextraSecretEnv:\n  GOOGLE_KEY: xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com\n  GOOGLE_SECRET: xxxxxxxxxxxxxxxxxxxxxxxx\n\nconfigOverrides:\n  enable_oauth: |\n    # This will make sure the redirect_uri is properly computed, even with SSL offloading\n    ENABLE_PROXY_FIX = True\n\n    from flask_appbuilder.security.manager import AUTH_OAUTH\n    AUTH_TYPE = AUTH_OAUTH\n    OAUTH_PROVIDERS = [\n        {\n            "name": "google",\n            "icon": "fa-google",\n            "token_key": "access_token",\n            "remote_app": {\n                "client_id": os.getenv("GOOGLE_KEY"),\n                "client_secret": os.getenv("GOOGLE_SECRET"),\n                "api_base_url": "https://www.googleapis.com/oauth2/v2/",\n                "client_kwargs": {"scope": "email profile"},\n                "request_token_url": None,\n                "access_token_url": "https://accounts.google.com/o/oauth2/token",\n                "authorize_url": "https://accounts.google.com/o/oauth2/auth",\n                "authorize_params": {"hd": os.getenv("AUTH_DOMAIN", "")}\n            },\n        }\n    ]\n\n    # Map Authlib roles to superset roles\n    AUTH_ROLE_ADMIN = \'Admin\'\n    AUTH_ROLE_PUBLIC = \'Public\'\n\n    # Will allow user self registration, allowing to create Flask users from Authorized User\n    AUTH_USER_REGISTRATION = True\n\n    # The default user self registration role\n    AUTH_USER_REGISTRATION_ROLE = "Admin"\n')),(0,r.kt)("h4",{id:"enable-alerts-and-reports"},"Enable Alerts and Reports"),(0,r.kt)("p",null,"For this, as per the ",(0,r.kt)("a",{parentName:"p",href:"/docs/installation/email-reports"},"Alerts and Reports doc"),", you will need to:"),(0,r.kt)("h5",{id:"install-a-supported-webdriver-in-the-celery-worker"},"Install a supported webdriver in the Celery worker"),(0,r.kt)("p",null,"This is done either by using a custom image that has the webdriver pre-installed, or installing at startup time by overriding the ",(0,r.kt)("inlineCode",{parentName:"p"},"command"),". Here's a working example for ",(0,r.kt)("inlineCode",{parentName:"p"},"chromedriver"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"supersetWorker:\n  command:\n    - /bin/sh\n    - -c\n    - |\n      # Install chrome webdriver\n      # See https://github.com/apache/superset/blob/4fa3b6c7185629b87c27fc2c0e5435d458f7b73d/docs/src/pages/docs/installation/email_reports.mdx\n      apt update\n      wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb\n      apt install -y --no-install-recommends ./google-chrome-stable_current_amd64.deb\n      wget https://chromedriver.storage.googleapis.com/88.0.4324.96/chromedriver_linux64.zip\n      unzip chromedriver_linux64.zip\n      chmod +x chromedriver\n      mv chromedriver /usr/bin\n      apt autoremove -yqq --purge\n      apt clean\n      rm -f google-chrome-stable_current_amd64.deb chromedriver_linux64.zip\n\n      # Run\n      . {{ .Values.configMountPath }}/superset_bootstrap.sh; celery --app=superset.tasks.celery_app:app worker\n")),(0,r.kt)("h5",{id:"run-the-celery-beat"},"Run the Celery beat"),(0,r.kt)("p",null,"This pod will trigger the scheduled tasks configured in the alerts and reports UI section:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"supersetCeleryBeat:\n  enabled: true\n")),(0,r.kt)("h5",{id:"configure-the-appropriate-celery-jobs-and-smtpslack-settings"},"Configure the appropriate Celery jobs and SMTP/Slack settings"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"extraEnv:\n  SMTP_HOST: smtp.gmail.com\n  SMTP_USER: user@gmail.com\n  SMTP_PORT: \"587\"\n  SMTP_MAIL_FROM: user@gmail.com\n\nextraSecretEnv:\n  SLACK_API_TOKEN: xoxb-xxxx-yyyy\n  SMTP_PASSWORD: xxxx-yyyy\n\nconfigOverrides:\n  feature_flags: |\n    import ast\n\n    FEATURE_FLAGS = {\n        \"ALERT_REPORTS\": True\n    }\n\n    SMTP_HOST = os.getenv(\"SMTP_HOST\",\"localhost\")\n    SMTP_STARTTLS = ast.literal_eval(os.getenv(\"SMTP_STARTTLS\", \"True\"))\n    SMTP_SSL = ast.literal_eval(os.getenv(\"SMTP_SSL\", \"False\"))\n    SMTP_USER = os.getenv(\"SMTP_USER\",\"superset\")\n    SMTP_PORT = os.getenv(\"SMTP_PORT\",25)\n    SMTP_PASSWORD = os.getenv(\"SMTP_PASSWORD\",\"superset\")\n    SMTP_MAIL_FROM = os.getenv(\"SMTP_MAIL_FROM\",\"superset@superset.com\")\n\n    SLACK_API_TOKEN = os.getenv(\"SLACK_API_TOKEN\",None)\n  celery_conf: |\n    from celery.schedules import crontab\n\n    class CeleryConfig(object):\n      broker_url = f\"redis://{env('REDIS_HOST')}:{env('REDIS_PORT')}/0\"\n      imports = ('superset.sql_lab', \"superset.tasks\", \"superset.tasks.thumbnails\", )\n      result_backend = f\"redis://{env('REDIS_HOST')}:{env('REDIS_PORT')}/0\"\n      task_annotations = {\n          'sql_lab.get_sql_results': {\n              'rate_limit': '100/s',\n          },\n          'email_reports.send': {\n              'rate_limit': '1/s',\n              'time_limit': 600,\n              'soft_time_limit': 600,\n              'ignore_result': True,\n          },\n      }\n      beat_schedule = {\n          'reports.scheduler': {\n              'task': 'reports.scheduler',\n              'schedule': crontab(minute='*', hour='*'),\n          },\n          'reports.prune_log': {\n              'task': 'reports.prune_log',\n              'schedule': crontab(minute=0, hour=0),\n          },\n          'cache-warmup-hourly': {\n              'task': 'cache-warmup',\n              'schedule': crontab(minute='*/30', hour='*'),\n              'kwargs': {\n                  'strategy_name': 'top_n_dashboards',\n                  'top_n': 10,\n                  'since': '7 days ago',\n              },\n          }\n      }\n\n    CELERY_CONFIG = CeleryConfig\n  reports: |\n    EMAIL_PAGE_RENDER_WAIT = 60\n    WEBDRIVER_BASEURL = \"http://{{ template \"superset.fullname\" . }}:{{ .Values.service.port }}/\"\n    WEBDRIVER_BASEURL_USER_FRIENDLY = \"https://www.example.com/\"\n    WEBDRIVER_TYPE= \"chrome\"\n    WEBDRIVER_OPTION_ARGS = [\n        \"--force-device-scale-factor=2.0\",\n        \"--high-dpi-support=2.0\",\n        \"--headless\",\n        \"--disable-gpu\",\n        \"--disable-dev-shm-usage\",\n        # This is required because our process runs as root (in order to install pip packages)\n        \"--no-sandbox\",\n        \"--disable-setuid-sandbox\",\n        \"--disable-extensions\",\n    ]\n")),(0,r.kt)("h4",{id:"load-the-examples-data-and-dashboards"},"Load the Examples data and dashboards"),(0,r.kt)("p",null,"If you are trying Superset out and want some data and dashboards to explore, you can load some examples by creating a ",(0,r.kt)("inlineCode",{parentName:"p"},"my_values.yaml")," and deploying it as described above in the ",(0,r.kt)("strong",{parentName:"p"},"Configure your setting overrides")," step of the ",(0,r.kt)("strong",{parentName:"p"},"Running")," section.\nTo load the examples, add the following to the ",(0,r.kt)("inlineCode",{parentName:"p"},"my_values.yaml")," file:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"init:\n  loadExamples: true\n")))}c.isMDXComponent=!0},3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>h});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?s(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):s(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function i(e,t){if(null==e)return{};var n,a,r=function(e,t){if(null==e)return{};var n,a,r={},s=Object.keys(e);for(a=0;a<s.length;a++)n=s[a],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a<s.length;a++)n=s[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var o=a.createContext({}),p=function(e){var t=a.useContext(o),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},u=function(e){var t=p(e.components);return a.createElement(o.Provider,{value:t},e.children)},d="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,s=e.originalType,o=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),d=p(n),m=r,h=d["".concat(o,".").concat(m)]||d[m]||c[m]||s;return n?a.createElement(h,l(l({ref:t},u),{},{components:n})):a.createElement(h,l({ref:t},u))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var s=n.length,l=new Array(s);l[0]=m;var i={};for(var o in t)hasOwnProperty.call(t,o)&&(i[o]=t[o]);i.originalType=e,i[d]="string"==typeof e?e:r,l[1]=i;for(var p=2;p<s;p++)l[p]=n[p];return a.createElement.apply(null,l)}return a.createElement.apply(null,n)}m.displayName="MDXCreateElement"}}]);
\ No newline at end of file
+"use strict";(self.webpackChunkdocs_v_2=self.webpackChunkdocs_v_2||[]).push([[9822],{25079:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>l,default:()=>c,frontMatter:()=>s,metadata:()=>i,toc:()=>p});var a=n(83117),r=(n(67294),n(3905));const s={title:"Installing on Kubernetes",hide_title:!0,sidebar_position:3,version:1},l=void 0,i={unversionedId:"installation/running-on-kubernetes",id:"installation/running-on-kubernetes",title:"Installing on Kubernetes",description:"Installing on Kubernetes",source:"@site/docs/installation/running-on-kubernetes.mdx",sourceDirName:"installation",slug:"/installation/running-on-kubernetes",permalink:"/docs/installation/running-on-kubernetes",draft:!1,editUrl:"https://github.com/apache/superset/tree/master/docs/docs/installation/running-on-kubernetes.mdx",tags:[],version:"current",sidebarPosition:3,frontMatter:{title:"Installing on Kubernetes",hide_title:!0,sidebar_position:3,version:1},sidebar:"tutorialSidebar",previous:{title:"Installing From Scratch",permalink:"/docs/installation/installing-superset-from-scratch"},next:{title:"Configuring Superset",permalink:"/docs/installation/configuring-superset"}},o={},p=[{value:"Installing on Kubernetes",id:"installing-on-kubernetes",level:2},{value:"Prerequisites",id:"prerequisites",level:3},{value:"Running",id:"running",level:3},{value:"Important settings",id:"important-settings",level:3},{value:"Security settings",id:"security-settings",level:4},{value:"Dependencies",id:"dependencies",level:4},{value:"superset_config.py",id:"superset_configpy",level:4},{value:"Environment Variables",id:"environment-variables",level:4},{value:"System packages",id:"system-packages",level:4},{value:"Data sources",id:"data-sources",level:4},{value:"Configuration Examples",id:"configuration-examples",level:3},{value:"Setting up OAuth",id:"setting-up-oauth",level:4},{value:"Enable Alerts and Reports",id:"enable-alerts-and-reports",level:4},{value:"Install a supported webdriver in the Celery worker",id:"install-a-supported-webdriver-in-the-celery-worker",level:5},{value:"Run the Celery beat",id:"run-the-celery-beat",level:5},{value:"Configure the appropriate Celery jobs and SMTP/Slack settings",id:"configure-the-appropriate-celery-jobs-and-smtpslack-settings",level:5},{value:"Load the Examples data and dashboards",id:"load-the-examples-data-and-dashboards",level:4}],u={toc:p},d="wrapper";function c(e){let{components:t,...n}=e;return(0,r.kt)(d,(0,a.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h2",{id:"installing-on-kubernetes"},"Installing on Kubernetes"),(0,r.kt)("p",null,"Running Superset on Kubernetes is supported with the provided ",(0,r.kt)("a",{parentName:"p",href:"https://helm.sh/"},"Helm")," chart found in the official ",(0,r.kt)("a",{parentName:"p",href:"https://apache.github.io/superset/index.yaml"},"Superset helm repository"),"."),(0,r.kt)("h3",{id:"prerequisites"},"Prerequisites"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"A Kubernetes cluster"),(0,r.kt)("li",{parentName:"ul"},"Helm installed")),(0,r.kt)("h3",{id:"running"},"Running"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Add the Superset helm repository")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},'helm repo add superset https://apache.github.io/superset\n"superset" has been added to your repositories\n')),(0,r.kt)("ol",{start:2},(0,r.kt)("li",{parentName:"ol"},"View charts in repo")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"helm search repo superset\nNAME                    CHART VERSION   APP VERSION     DESCRIPTION\nsuperset/superset       0.1.1           1.0             Apache Superset is a modern, enterprise-ready b...\n")),(0,r.kt)("ol",{start:3},(0,r.kt)("li",{parentName:"ol"},"Configure your setting overrides")),(0,r.kt)("p",null,"Just like any typical Helm chart, you'll need to craft a ",(0,r.kt)("inlineCode",{parentName:"p"},"values.yaml")," file that would define/override any of the values exposed into the default ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/apache/superset/tree/master/helm/superset/values.yaml"},"values.yaml"),", or from any of the dependent charts it depends on:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://artifacthub.io/packages/helm/bitnami/redis"},"bitnami/redis")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://artifacthub.io/packages/helm/bitnami/postgresql"},"bitnami/postgresql"))),(0,r.kt)("p",null,"More info down below on some important overrides you might need."),(0,r.kt)("ol",{start:4},(0,r.kt)("li",{parentName:"ol"},"Install and run")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"helm upgrade --install --values my-values.yaml superset superset/superset\n")),(0,r.kt)("p",null,"You should see various pods popping up, such as:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"kubectl get pods\nNAME                                    READY   STATUS      RESTARTS   AGE\nsuperset-celerybeat-7cdcc9575f-k6xmc    1/1     Running     0          119s\nsuperset-f5c9c667-dw9lp                 1/1     Running     0          4m7s\nsuperset-f5c9c667-fk8bk                 1/1     Running     0          4m11s\nsuperset-init-db-zlm9z                  0/1     Completed   0          111s\nsuperset-postgresql-0                   1/1     Running     0          6d20h\nsuperset-redis-master-0                 1/1     Running     0          6d20h\nsuperset-worker-75b48bbcc-jmmjr         1/1     Running     0          4m8s\nsuperset-worker-75b48bbcc-qrq49         1/1     Running     0          4m12s\n")),(0,r.kt)("p",null,"The exact list will depend on some of your specific configuration overrides but you should generally expect:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"N ",(0,r.kt)("inlineCode",{parentName:"li"},"superset-xxxx-yyyy")," and ",(0,r.kt)("inlineCode",{parentName:"li"},"superset-worker-xxxx-yyyy")," pods (depending on your ",(0,r.kt)("inlineCode",{parentName:"li"},"supersetNode.replicaCount")," and ",(0,r.kt)("inlineCode",{parentName:"li"},"supersetWorker.replicaCount")," values)"),(0,r.kt)("li",{parentName:"ul"},"1 ",(0,r.kt)("inlineCode",{parentName:"li"},"superset-postgresql-0")," depending on your postgres settings"),(0,r.kt)("li",{parentName:"ul"},"1 ",(0,r.kt)("inlineCode",{parentName:"li"},"superset-redis-master-0")," depending on your redis settings"),(0,r.kt)("li",{parentName:"ul"},"1 ",(0,r.kt)("inlineCode",{parentName:"li"},"superset-celerybeat-xxxx-yyyy")," pod if you have ",(0,r.kt)("inlineCode",{parentName:"li"},"supersetCeleryBeat.enabled = true")," in your values overrides")),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Access it")),(0,r.kt)("p",null,"The chart will publish appropriate services to expose the Superset UI internally within your k8s cluster. To access it externally you will have to either:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Configure the Service as a ",(0,r.kt)("inlineCode",{parentName:"li"},"LoadBalancer")," or ",(0,r.kt)("inlineCode",{parentName:"li"},"NodePort")),(0,r.kt)("li",{parentName:"ul"},"Set up an ",(0,r.kt)("inlineCode",{parentName:"li"},"Ingress")," for it - the chart includes a definition, but will need to be tuned to your needs (hostname, tls, annotations etc...)"),(0,r.kt)("li",{parentName:"ul"},"Run ",(0,r.kt)("inlineCode",{parentName:"li"},"kubectl port-forward superset-xxxx-yyyy :8088")," to directly tunnel one pod's port into your localhost")),(0,r.kt)("p",null,"Depending how you configured external access, the URL will vary. Once you've identified the appropriate URL you can log in with:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"user: ",(0,r.kt)("inlineCode",{parentName:"li"},"admin")),(0,r.kt)("li",{parentName:"ul"},"password: ",(0,r.kt)("inlineCode",{parentName:"li"},"admin"))),(0,r.kt)("h3",{id:"important-settings"},"Important settings"),(0,r.kt)("h4",{id:"security-settings"},"Security settings"),(0,r.kt)("p",null,"Default security settings and passwords are included but you ",(0,r.kt)("strong",{parentName:"p"},"SHOULD")," override those with your own, in particular:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"postgresql:\n  postgresqlPassword: superset\n")),(0,r.kt)("p",null,"Make sure, you set a unique strong complex alphanumeric string for your SECRET_KEY and use a tool to help you generate\na sufficiently random sequence."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"To generate a good key you can run, ",(0,r.kt)("inlineCode",{parentName:"li"},"openssl rand -base64 42"))),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"configOverrides:\n  secret: |\n    SECRET_KEY = 'YOUR_OWN_RANDOM_GENERATED_SECRET_KEY'\n")),(0,r.kt)("p",null,"If you want to change the previous secret key then you should rotate the keys.\nDefault secret key for kubernetes deployment is ",(0,r.kt)("inlineCode",{parentName:"p"},"thisISaSECRET_1234")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"configOverrides:\n  my_override: |\n    PREVIOUS_SECRET_KEY = 'YOUR_PREVIOUS_SECRET_KEY'\n    SECRET_KEY = 'YOUR_OWN_RANDOM_GENERATED_SECRET_KEY'\ninit:\n  command:\n    - /bin/sh\n    - -c\n    - |\n      . {{ .Values.configMountPath }}/superset_bootstrap.sh\n      superset re-encrypt-secrets\n      . {{ .Values.configMountPath }}/superset_init.sh\n")),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"Superset uses ",(0,r.kt)("a",{parentName:"p",href:"https://about.scarf.sh/scarf-gateway"},"Scarf Gateway")," to collect telemetry data.  Knowing the installation counts for different Superset versions informs the  project's decisions about patching and long-term support. Scarf purges personally identifiable information (PII) and provides only aggregated statistics."),(0,r.kt)("p",{parentName:"admonition"},"To opt-out of this data collection in your Helm-based installation, edit the ",(0,r.kt)("inlineCode",{parentName:"p"},"repository:")," line in your ",(0,r.kt)("inlineCode",{parentName:"p"},"helm/superset/values.yaml")," file, replacing ",(0,r.kt)("inlineCode",{parentName:"p"},"apachesuperset.docker.scarf.sh/apache/superset")," with ",(0,r.kt)("inlineCode",{parentName:"p"},"apache/superset")," to pull the image directly from Docker Hub.")),(0,r.kt)("h4",{id:"dependencies"},"Dependencies"),(0,r.kt)("p",null,"Install additional packages and do any other bootstrap configuration in the bootstrap script.\nFor production clusters it's recommended to build own image with this step done in CI."),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"Superset requires a Python DB-API database driver and a SQLAlchemy\ndialect to be installed for each datastore you want to connect to."),(0,r.kt)("p",{parentName:"admonition"},"See ",(0,r.kt)("a",{parentName:"p",href:"/docs/databases/installing-database-drivers"},"Install Database Drivers")," for more information.")),(0,r.kt)("p",null,"The following example installs the Big Query and Elasticsearch database drivers so that you can\nconnect to those datasources in your Superset installation:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'bootstrapScript: |\n  #!/bin/bash\n  pip install psycopg2==2.9.6 \\\n    sqlalchemy-bigquery==1.6.1 \\\n    elasticsearch-dbapi==0.2.5 &&\\\n  if [ ! -f ~/bootstrap ]; then echo "Running Superset with uid {{ .Values.runAsUser }}" > ~/bootstrap; fi\n')),(0,r.kt)("h4",{id:"superset_configpy"},"superset_config.py"),(0,r.kt)("p",null,"The default ",(0,r.kt)("inlineCode",{parentName:"p"},"superset_config.py")," is fairly minimal and you will very likely need to extend it. This is done by specifying one or more key/value entries in ",(0,r.kt)("inlineCode",{parentName:"p"},"configOverrides"),", e.g.:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'configOverrides:\n  my_override: |\n    # This will make sure the redirect_uri is properly computed, even with SSL offloading\n    ENABLE_PROXY_FIX = True\n    FEATURE_FLAGS = {\n        "DYNAMIC_PLUGINS": True\n    }\n')),(0,r.kt)("p",null,"Those will be evaluated as Helm templates and therefore will be able to reference other ",(0,r.kt)("inlineCode",{parentName:"p"},"values.yaml")," variables e.g. ",(0,r.kt)("inlineCode",{parentName:"p"},"{{ .Values.ingress.hosts[0] }}")," will resolve to your ingress external domain."),(0,r.kt)("p",null,"The entire ",(0,r.kt)("inlineCode",{parentName:"p"},"superset_config.py")," will be installed as a secret, so it is safe to pass sensitive parameters directly... however it might be more readable to use secret env variables for that."),(0,r.kt)("p",null,"Full python files can be provided by running ",(0,r.kt)("inlineCode",{parentName:"p"},"helm upgrade --install --values my-values.yaml --set-file configOverrides.oauth=set_oauth.py")),(0,r.kt)("h4",{id:"environment-variables"},"Environment Variables"),(0,r.kt)("p",null,"Those can be passed as key/values either with ",(0,r.kt)("inlineCode",{parentName:"p"},"extraEnv")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"extraSecretEnv")," if they're sensitive. They can then be referenced from ",(0,r.kt)("inlineCode",{parentName:"p"},"superset_config.py")," using e.g. ",(0,r.kt)("inlineCode",{parentName:"p"},'os.environ.get("VAR")'),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'extraEnv:\n  SMTP_HOST: smtp.gmail.com\n  SMTP_USER: user@gmail.com\n  SMTP_PORT: "587"\n  SMTP_MAIL_FROM: user@gmail.com\n\nextraSecretEnv:\n  SMTP_PASSWORD: xxxx\n\nconfigOverrides:\n  smtp: |\n    import ast\n    SMTP_HOST = os.getenv("SMTP_HOST","localhost")\n    SMTP_STARTTLS = ast.literal_eval(os.getenv("SMTP_STARTTLS", "True"))\n    SMTP_SSL = ast.literal_eval(os.getenv("SMTP_SSL", "False"))\n    SMTP_USER = os.getenv("SMTP_USER","superset")\n    SMTP_PORT = os.getenv("SMTP_PORT",25)\n    SMTP_PASSWORD = os.getenv("SMTP_PASSWORD","superset")\n')),(0,r.kt)("h4",{id:"system-packages"},"System packages"),(0,r.kt)("p",null,"If new system packages are required, they can be installed before application startup by overriding the container's ",(0,r.kt)("inlineCode",{parentName:"p"},"command"),", e.g.:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"supersetWorker:\n  command:\n    - /bin/sh\n    - -c\n    - |\n      apt update\n      apt install -y somepackage\n      apt autoremove -yqq --purge\n      apt clean\n\n      # Run celery worker\n      . {{ .Values.configMountPath }}/superset_bootstrap.sh; celery --app=superset.tasks.celery_app:app worker\n")),(0,r.kt)("h4",{id:"data-sources"},"Data sources"),(0,r.kt)("p",null,"Data source definitions can be automatically declared by providing key/value yaml definitions in ",(0,r.kt)("inlineCode",{parentName:"p"},"extraConfigs"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'extraConfigs:\n  import_datasources.yaml: |\n    databases:\n    - allow_file_upload: true\n      allow_ctas: true\n      allow_cvas: true\n      database_name: example-db\n      extra: "{\\r\\n    \\"metadata_params\\": {},\\r\\n    \\"engine_params\\": {},\\r\\n    \\"\\\n        metadata_cache_timeout\\": {},\\r\\n    \\"schemas_allowed_for_file_upload\\": []\\r\\n\\\n        }"\n      sqlalchemy_uri: example://example-db.local\n      tables: []\n')),(0,r.kt)("p",null,"Those will also be mounted as secrets and can include sensitive parameters."),(0,r.kt)("h3",{id:"configuration-examples"},"Configuration Examples"),(0,r.kt)("h4",{id:"setting-up-oauth"},"Setting up OAuth"),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"OAuth setup requires that the ",(0,r.kt)("a",{parentName:"p",href:"https://authlib.org/"},"authlib")," Python library is installed. This can\nbe done using ",(0,r.kt)("inlineCode",{parentName:"p"},"pip")," by updating the ",(0,r.kt)("inlineCode",{parentName:"p"},"bootstrapScript"),". See the ",(0,r.kt)("a",{parentName:"p",href:"#dependencies"},"Dependencies")," section\nfor more information.")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'extraEnv:\n  AUTH_DOMAIN: example.com\n\nextraSecretEnv:\n  GOOGLE_KEY: xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com\n  GOOGLE_SECRET: xxxxxxxxxxxxxxxxxxxxxxxx\n\nconfigOverrides:\n  enable_oauth: |\n    # This will make sure the redirect_uri is properly computed, even with SSL offloading\n    ENABLE_PROXY_FIX = True\n\n    from flask_appbuilder.security.manager import AUTH_OAUTH\n    AUTH_TYPE = AUTH_OAUTH\n    OAUTH_PROVIDERS = [\n        {\n            "name": "google",\n            "icon": "fa-google",\n            "token_key": "access_token",\n            "remote_app": {\n                "client_id": os.getenv("GOOGLE_KEY"),\n                "client_secret": os.getenv("GOOGLE_SECRET"),\n                "api_base_url": "https://www.googleapis.com/oauth2/v2/",\n                "client_kwargs": {"scope": "email profile"},\n                "request_token_url": None,\n                "access_token_url": "https://accounts.google.com/o/oauth2/token",\n                "authorize_url": "https://accounts.google.com/o/oauth2/auth",\n                "authorize_params": {"hd": os.getenv("AUTH_DOMAIN", "")}\n            },\n        }\n    ]\n\n    # Map Authlib roles to superset roles\n    AUTH_ROLE_ADMIN = \'Admin\'\n    AUTH_ROLE_PUBLIC = \'Public\'\n\n    # Will allow user self registration, allowing to create Flask users from Authorized User\n    AUTH_USER_REGISTRATION = True\n\n    # The default user self registration role\n    AUTH_USER_REGISTRATION_ROLE = "Admin"\n')),(0,r.kt)("h4",{id:"enable-alerts-and-reports"},"Enable Alerts and Reports"),(0,r.kt)("p",null,"For this, as per the ",(0,r.kt)("a",{parentName:"p",href:"/docs/installation/email-reports"},"Alerts and Reports doc"),", you will need to:"),(0,r.kt)("h5",{id:"install-a-supported-webdriver-in-the-celery-worker"},"Install a supported webdriver in the Celery worker"),(0,r.kt)("p",null,"This is done either by using a custom image that has the webdriver pre-installed, or installing at startup time by overriding the ",(0,r.kt)("inlineCode",{parentName:"p"},"command"),". Here's a working example for ",(0,r.kt)("inlineCode",{parentName:"p"},"chromedriver"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"supersetWorker:\n  command:\n    - /bin/sh\n    - -c\n    - |\n      # Install chrome webdriver\n      # See https://github.com/apache/superset/blob/4fa3b6c7185629b87c27fc2c0e5435d458f7b73d/docs/src/pages/docs/installation/email_reports.mdx\n      apt update\n      wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb\n      apt install -y --no-install-recommends ./google-chrome-stable_current_amd64.deb\n      wget https://chromedriver.storage.googleapis.com/88.0.4324.96/chromedriver_linux64.zip\n      unzip chromedriver_linux64.zip\n      chmod +x chromedriver\n      mv chromedriver /usr/bin\n      apt autoremove -yqq --purge\n      apt clean\n      rm -f google-chrome-stable_current_amd64.deb chromedriver_linux64.zip\n\n      # Run\n      . {{ .Values.configMountPath }}/superset_bootstrap.sh; celery --app=superset.tasks.celery_app:app worker\n")),(0,r.kt)("h5",{id:"run-the-celery-beat"},"Run the Celery beat"),(0,r.kt)("p",null,"This pod will trigger the scheduled tasks configured in the alerts and reports UI section:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"supersetCeleryBeat:\n  enabled: true\n")),(0,r.kt)("h5",{id:"configure-the-appropriate-celery-jobs-and-smtpslack-settings"},"Configure the appropriate Celery jobs and SMTP/Slack settings"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'extraEnv:\n  SMTP_HOST: smtp.gmail.com\n  SMTP_USER: user@gmail.com\n  SMTP_PORT: "587"\n  SMTP_MAIL_FROM: user@gmail.com\n\nextraSecretEnv:\n  SLACK_API_TOKEN: xoxb-xxxx-yyyy\n  SMTP_PASSWORD: xxxx-yyyy\n\nconfigOverrides:\n  feature_flags: |\n    import ast\n\n    FEATURE_FLAGS = {\n        "ALERT_REPORTS": True\n    }\n\n    SMTP_HOST = os.getenv("SMTP_HOST","localhost")\n    SMTP_STARTTLS = ast.literal_eval(os.getenv("SMTP_STARTTLS", "True"))\n    SMTP_SSL = ast.literal_eval(os.getenv("SMTP_SSL", "False"))\n    SMTP_USER = os.getenv("SMTP_USER","superset")\n    SMTP_PORT = os.getenv("SMTP_PORT",25)\n    SMTP_PASSWORD = os.getenv("SMTP_PASSWORD","superset")\n    SMTP_MAIL_FROM = os.getenv("SMTP_MAIL_FROM","superset@superset.com")\n\n    SLACK_API_TOKEN = os.getenv("SLACK_API_TOKEN",None)\n  celery_conf: |\n    from celery.schedules import crontab\n\n    class CeleryConfig:\n      broker_url = f"redis://{env(\'REDIS_HOST\')}:{env(\'REDIS_PORT\')}/0"\n      imports = (\n          "superset.sql_lab",\n          "superset.tasks.cache",\n          "superset.tasks.scheduler",\n      )\n      result_backend = f"redis://{env(\'REDIS_HOST\')}:{env(\'REDIS_PORT\')}/0"\n      task_annotations = {\n          "sql_lab.get_sql_results": {\n              "rate_limit": "100/s",\n          },\n      }\n      beat_schedule = {\n          "reports.scheduler": {\n              "task": "reports.scheduler",\n              "schedule": crontab(minute="*", hour="*"),\n          },\n          "reports.prune_log": {\n              "task": "reports.prune_log",\n              \'schedule\': crontab(minute=0, hour=0),\n          },\n          \'cache-warmup-hourly\': {\n              "task": "cache-warmup",\n              "schedule": crontab(minute="*/30", hour="*"),\n              "kwargs": {\n                  "strategy_name": "top_n_dashboards",\n                  "top_n": 10,\n                  "since": "7 days ago",\n              },\n          }\n      }\n\n    CELERY_CONFIG = CeleryConfig\n  reports: |\n    EMAIL_PAGE_RENDER_WAIT = 60\n    WEBDRIVER_BASEURL = "http://{{ template "superset.fullname" . }}:{{ .Values.service.port }}/"\n    WEBDRIVER_BASEURL_USER_FRIENDLY = "https://www.example.com/"\n    WEBDRIVER_TYPE= "chrome"\n    WEBDRIVER_OPTION_ARGS = [\n        "--force-device-scale-factor=2.0",\n        "--high-dpi-support=2.0",\n        "--headless",\n        "--disable-gpu",\n        "--disable-dev-shm-usage",\n        # This is required because our process runs as root (in order to install pip packages)\n        "--no-sandbox",\n        "--disable-setuid-sandbox",\n        "--disable-extensions",\n    ]\n')),(0,r.kt)("h4",{id:"load-the-examples-data-and-dashboards"},"Load the Examples data and dashboards"),(0,r.kt)("p",null,"If you are trying Superset out and want some data and dashboards to explore, you can load some examples by creating a ",(0,r.kt)("inlineCode",{parentName:"p"},"my_values.yaml")," and deploying it as described above in the ",(0,r.kt)("strong",{parentName:"p"},"Configure your setting overrides")," step of the ",(0,r.kt)("strong",{parentName:"p"},"Running")," section.\nTo load the examples, add the following to the ",(0,r.kt)("inlineCode",{parentName:"p"},"my_values.yaml")," file:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"init:\n  loadExamples: true\n")))}c.isMDXComponent=!0},3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>h});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?s(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):s(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function i(e,t){if(null==e)return{};var n,a,r=function(e,t){if(null==e)return{};var n,a,r={},s=Object.keys(e);for(a=0;a<s.length;a++)n=s[a],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a<s.length;a++)n=s[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var o=a.createContext({}),p=function(e){var t=a.useContext(o),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},u=function(e){var t=p(e.components);return a.createElement(o.Provider,{value:t},e.children)},d="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,s=e.originalType,o=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),d=p(n),m=r,h=d["".concat(o,".").concat(m)]||d[m]||c[m]||s;return n?a.createElement(h,l(l({ref:t},u),{},{components:n})):a.createElement(h,l({ref:t},u))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var s=n.length,l=new Array(s);l[0]=m;var i={};for(var o in t)hasOwnProperty.call(t,o)&&(i[o]=t[o]);i.originalType=e,i[d]="string"==typeof e?e:r,l[1]=i;for(var p=2;p<s;p++)l[p]=n[p];return a.createElement.apply(null,l)}return a.createElement.apply(null,n)}m.displayName="MDXCreateElement"}}]);
\ No newline at end of file
diff --git a/assets/js/runtime~main.da047873.js b/assets/js/runtime~main.ac9c8adb.js
similarity index 96%
rename from assets/js/runtime~main.da047873.js
rename to assets/js/runtime~main.ac9c8adb.js
index 211d1aa..3e234ab 100644
--- a/assets/js/runtime~main.da047873.js
+++ b/assets/js/runtime~main.ac9c8adb.js
@@ -1 +1 @@
-(()=>{"use strict";var e,a,c,f,d,b={},t={};function r(e){var a=t[e];if(void 0!==a)return a.exports;var c=t[e]={id:e,loaded:!1,exports:{}};return b[e].call(c.exports,c,c.exports,r),c.loaded=!0,c.exports}r.m=b,r.c=t,e=[],r.O=(a,c,f,d)=>{if(!c){var b=1/0;for(i=0;i<e.length;i++){c=e[i][0],f=e[i][1],d=e[i][2];for(var t=!0,o=0;o<c.length;o++)(!1&d||b>=d)&&Object.keys(r.O).every((e=>r.O[e](c[o])))?c.splice(o--,1):(t=!1,d<b&&(b=d));if(t){e.splice(i--,1);var n=f();void 0!==n&&(a=n)}}return a}d=d||0;for(var i=e.length;i>0&&e[i-1][2]>d;i--)e[i]=e[i-1];e[i]=[c,f,d]},r.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return r.d(a,{a:a}),a},c=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,f){if(1&f&&(e=this(e)),8&f)return e;if("object"==typeof e&&e){if(4&f&&e.__esModule)return e;if(16&f&&"function"==typeof e.then)return e}var d=Object.create(null);r.r(d);var b={};a=a||[null,c({}),c([]),c(c)];for(var t=2&f&&e;"object"==typeof t&&!~a.indexOf(t);t=c(t))Object.getOwnPropertyNames(t).forEach((a=>b[a]=()=>e[a]));return b.default=()=>e,r.d(d,b),d},r.d=(e,a)=>{for(var c in a)r.o(a,c)&&!r.o(e,c)&&Object.defineProperty(e,c,{enumerable:!0,get:a[c]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((a,c)=>(r.f[c](e,a),a)),[])),r.u=e=>"assets/js/"+({53:"935f2afb",112:"afef705c",229:"25f17725",340:"070b53d1",396:"0ae8b3d4",515:"53bb5fc4",599:"3c585fdb",674:"67158350",742:"dd0670d3",907:"c1424005",1083:"bd23e567",1444:"69a4ab96",1533:"6edc47f3",1964:"5e15fec9",2331:"19682bb8",2429:"d5417e33",2942:"eb23a929",3085:"1f391b9e",3206:"f8409a7e",3237:"1df93b7f",3628:"fa1a3aa0",3672:"cf6ffe2f",3775:"496bf018",3821:"21b4b958",3909:"cd90435d",3945:"a309f86e",3996:"9791fd42",4003:"6432bc55",4014:"5e50ba72",4096:"c76f729d",4244:"4cc2c078",4281:"1c734f75",4343:"18cf5ace",4490:"262418cd",4519:"2c412ea7",4586:"dc3fdd24",4628:"1ce51947",4729:"0c21af39",4745:"30ec1363",4796:"471df853",4992:"dc737160",5097:"a584ba2a",5114:"5ea65e65",5324:"a9e1a7f6",5542:"729f57ad",5551:"da60bc8f",5643:"30334fcd",5720:"30256b0d",5851:"8660bbc8",5906:"e7c796a6",6126:"e0a8f778",6230:"2bafca50",6455:"4e664dc4",6547:"1c42a294",6552:"6948bca1",6849:"57b59cd4",6860:"dbb131dd",7107:"d76e6194",7251:"9d6fd8ea",7271:"6a90d500",7285:"b92f705c",7380:"640bc8a0",7414:"393be207",7566:"972382ea",7587:"3ec2c3f7",7600:"2461ffa2",7706:"ce3fa444",7886:"5818c28e",7918:"17896441",7920:"1a4e3797",7937:"9a9c044b",8005:"600a9360",8015:"0e9953cd",8342:"eb3b0997",8402:"3c835dee",8561:"07f0ce13",8597:"f4a6e698",8718:"31e90f3c",8784:"35a5de3c",8835:"36ea7a08",8844:"b46ab14b",8853:"c296437a",8860:"71cf7fe6",8888:"ee5d850a",8915:"f9cc156b",9243:"40974919",9317:"f5f07875",9514:"1be78505",9594:"507542a3",9596:"88eaec5a",9609:"58160c0b",9617:"d83b78fc",9623:"904d61ef",9822:"fe0957ee"}[e]||e)+"."+{53:"d76597f4",112:"358a028d",229:"382b9496",340:"75523673",396:"e41dcf26",515:"d6fdf9a0",599:"ef01a5ad",674:"a3276773",713:"e8404ec1",742:"d68d210e",907:"df948777",975:"d95e9177",1083:"dc758238",1273:"c177fe37",1444:"8e098be3",1529:"cb77c953",1533:"74bc8988",1964:"bc80b38a",2331:"12ef5623",2387:"cf729afe",2429:"7d9140aa",2942:"7e9562fc",3085:"fabb506c",3206:"697ea5cb",3237:"bb60de38",3628:"e87e1188",3672:"2621ec01",3775:"c0c9431f",3821:"0e4bb161",3909:"99f961ac",3945:"fd5212eb",3996:"b79f756c",4003:"ace5d07c",4014:"2b277921",4096:"c85e22b7",4244:"1e2d58c9",4281:"fbd5783e",4343:"e12f7ce7",4357:"c9ab8a8e",4471:"bf33ef73",4490:"d10e768c",4519:"5753c5cd",4586:"b8268e5c",4628:"9c631359",4729:"2a013c27",4745:"e8758441",4796:"39c95442",4992:"1b73fe9a",5097:"a786479b",5114:"ffa26b77",5324:"d436de2e",5542:"f2ed3507",5551:"18262bd8",5643:"b5a32572",5720:"be106e3e",5851:"ad0f3e8d",5906:"9d01f089",5957:"4fb6e613",6126:"c43c04dc",6230:"7f7fb7ca",6455:"426e997b",6547:"6bff09cc",6552:"cde86692",6780:"ba84af4e",6849:"6dca875c",6860:"c82e4e25",6945:"d18f3d89",7029:"96f14d38",7107:"54d240ef",7251:"9ebcbca9",7271:"5d70da37",7285:"f7bd038b",7380:"2f6a629a",7414:"20dae7da",7566:"391f2ca7",7587:"6f37a44b",7600:"43c28611",7706:"62a49085",7886:"56d86c2e",7918:"156729cb",7920:"8a952348",7937:"9da8e8a6",8005:"0b984638",8015:"6d25c537",8342:"47b0e1a4",8402:"63cab2ea",8561:"4aefae82",8597:"891ffbff",8718:"a0004b49",8784:"cc424d0a",8835:"b650668e",8844:"0b23475f",8853:"7dc8f3c7",8860:"7dc81586",8888:"28a37eb6",8915:"ea4252e6",9169:"36534697",9243:"a133cd88",9317:"56314c09",9514:"bfe07248",9594:"e5fff5b5",9596:"0ba04755",9609:"0078e71d",9617:"4bd95169",9623:"107093cb",9822:"f71b66b9"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),f={},d="docs-v-2:",r.l=(e,a,c,b)=>{if(f[e])f[e].push(a);else{var t,o;if(void 0!==c)for(var n=document.getElementsByTagName("script"),i=0;i<n.length;i++){var l=n[i];if(l.getAttribute("src")==e||l.getAttribute("data-webpack")==d+c){t=l;break}}t||(o=!0,(t=document.createElement("script")).charset="utf-8",t.timeout=120,r.nc&&t.setAttribute("nonce",r.nc),t.setAttribute("data-webpack",d+c),t.src=e),f[e]=[a];var u=(a,c)=>{t.onerror=t.onload=null,clearTimeout(s);var d=f[e];if(delete f[e],t.parentNode&&t.parentNode.removeChild(t),d&&d.forEach((e=>e(c))),a)return a(c)},s=setTimeout(u.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=u.bind(null,t.onerror),t.onload=u.bind(null,t.onload),o&&document.head.appendChild(t)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),r.p="/",r.gca=function(e){return e={17896441:"7918",40974919:"9243",67158350:"674","935f2afb":"53",afef705c:"112","25f17725":"229","070b53d1":"340","0ae8b3d4":"396","53bb5fc4":"515","3c585fdb":"599",dd0670d3:"742",c1424005:"907",bd23e567:"1083","69a4ab96":"1444","6edc47f3":"1533","5e15fec9":"1964","19682bb8":"2331",d5417e33:"2429",eb23a929:"2942","1f391b9e":"3085",f8409a7e:"3206","1df93b7f":"3237",fa1a3aa0:"3628",cf6ffe2f:"3672","496bf018":"3775","21b4b958":"3821",cd90435d:"3909",a309f86e:"3945","9791fd42":"3996","6432bc55":"4003","5e50ba72":"4014",c76f729d:"4096","4cc2c078":"4244","1c734f75":"4281","18cf5ace":"4343","262418cd":"4490","2c412ea7":"4519",dc3fdd24:"4586","1ce51947":"4628","0c21af39":"4729","30ec1363":"4745","471df853":"4796",dc737160:"4992",a584ba2a:"5097","5ea65e65":"5114",a9e1a7f6:"5324","729f57ad":"5542",da60bc8f:"5551","30334fcd":"5643","30256b0d":"5720","8660bbc8":"5851",e7c796a6:"5906",e0a8f778:"6126","2bafca50":"6230","4e664dc4":"6455","1c42a294":"6547","6948bca1":"6552","57b59cd4":"6849",dbb131dd:"6860",d76e6194:"7107","9d6fd8ea":"7251","6a90d500":"7271",b92f705c:"7285","640bc8a0":"7380","393be207":"7414","972382ea":"7566","3ec2c3f7":"7587","2461ffa2":"7600",ce3fa444:"7706","5818c28e":"7886","1a4e3797":"7920","9a9c044b":"7937","600a9360":"8005","0e9953cd":"8015",eb3b0997:"8342","3c835dee":"8402","07f0ce13":"8561",f4a6e698:"8597","31e90f3c":"8718","35a5de3c":"8784","36ea7a08":"8835",b46ab14b:"8844",c296437a:"8853","71cf7fe6":"8860",ee5d850a:"8888",f9cc156b:"8915",f5f07875:"9317","1be78505":"9514","507542a3":"9594","88eaec5a":"9596","58160c0b":"9609",d83b78fc:"9617","904d61ef":"9623",fe0957ee:"9822"}[e]||e,r.p+r.u(e)},(()=>{var e={1303:0,532:0};r.f.j=(a,c)=>{var f=r.o(e,a)?e[a]:void 0;if(0!==f)if(f)c.push(f[2]);else if(/^(1303|532)$/.test(a))e[a]=0;else{var d=new Promise(((c,d)=>f=e[a]=[c,d]));c.push(f[2]=d);var b=r.p+r.u(a),t=new Error;r.l(b,(c=>{if(r.o(e,a)&&(0!==(f=e[a])&&(e[a]=void 0),f)){var d=c&&("load"===c.type?"missing":c.type),b=c&&c.target&&c.target.src;t.message="Loading chunk "+a+" failed.\n("+d+": "+b+")",t.name="ChunkLoadError",t.type=d,t.request=b,f[1](t)}}),"chunk-"+a,a)}},r.O.j=a=>0===e[a];var a=(a,c)=>{var f,d,b=c[0],t=c[1],o=c[2],n=0;if(b.some((a=>0!==e[a]))){for(f in t)r.o(t,f)&&(r.m[f]=t[f]);if(o)var i=o(r)}for(a&&a(c);n<b.length;n++)d=b[n],r.o(e,d)&&e[d]&&e[d][0](),e[d]=0;return r.O(i)},c=self.webpackChunkdocs_v_2=self.webpackChunkdocs_v_2||[];c.forEach(a.bind(null,0)),c.push=a.bind(null,c.push.bind(c))})()})();
\ No newline at end of file
+(()=>{"use strict";var e,a,c,f,d,b={},t={};function r(e){var a=t[e];if(void 0!==a)return a.exports;var c=t[e]={id:e,loaded:!1,exports:{}};return b[e].call(c.exports,c,c.exports,r),c.loaded=!0,c.exports}r.m=b,r.c=t,e=[],r.O=(a,c,f,d)=>{if(!c){var b=1/0;for(i=0;i<e.length;i++){c=e[i][0],f=e[i][1],d=e[i][2];for(var t=!0,o=0;o<c.length;o++)(!1&d||b>=d)&&Object.keys(r.O).every((e=>r.O[e](c[o])))?c.splice(o--,1):(t=!1,d<b&&(b=d));if(t){e.splice(i--,1);var n=f();void 0!==n&&(a=n)}}return a}d=d||0;for(var i=e.length;i>0&&e[i-1][2]>d;i--)e[i]=e[i-1];e[i]=[c,f,d]},r.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return r.d(a,{a:a}),a},c=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,f){if(1&f&&(e=this(e)),8&f)return e;if("object"==typeof e&&e){if(4&f&&e.__esModule)return e;if(16&f&&"function"==typeof e.then)return e}var d=Object.create(null);r.r(d);var b={};a=a||[null,c({}),c([]),c(c)];for(var t=2&f&&e;"object"==typeof t&&!~a.indexOf(t);t=c(t))Object.getOwnPropertyNames(t).forEach((a=>b[a]=()=>e[a]));return b.default=()=>e,r.d(d,b),d},r.d=(e,a)=>{for(var c in a)r.o(a,c)&&!r.o(e,c)&&Object.defineProperty(e,c,{enumerable:!0,get:a[c]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((a,c)=>(r.f[c](e,a),a)),[])),r.u=e=>"assets/js/"+({53:"935f2afb",112:"afef705c",229:"25f17725",340:"070b53d1",396:"0ae8b3d4",515:"53bb5fc4",599:"3c585fdb",674:"67158350",742:"dd0670d3",907:"c1424005",1083:"bd23e567",1444:"69a4ab96",1533:"6edc47f3",1964:"5e15fec9",2331:"19682bb8",2429:"d5417e33",2942:"eb23a929",3085:"1f391b9e",3206:"f8409a7e",3237:"1df93b7f",3628:"fa1a3aa0",3672:"cf6ffe2f",3775:"496bf018",3821:"21b4b958",3909:"cd90435d",3945:"a309f86e",3996:"9791fd42",4003:"6432bc55",4014:"5e50ba72",4096:"c76f729d",4244:"4cc2c078",4281:"1c734f75",4343:"18cf5ace",4490:"262418cd",4519:"2c412ea7",4586:"dc3fdd24",4628:"1ce51947",4729:"0c21af39",4745:"30ec1363",4796:"471df853",4992:"dc737160",5097:"a584ba2a",5114:"5ea65e65",5324:"a9e1a7f6",5542:"729f57ad",5551:"da60bc8f",5643:"30334fcd",5720:"30256b0d",5851:"8660bbc8",5906:"e7c796a6",6126:"e0a8f778",6230:"2bafca50",6455:"4e664dc4",6547:"1c42a294",6552:"6948bca1",6849:"57b59cd4",6860:"dbb131dd",7107:"d76e6194",7251:"9d6fd8ea",7271:"6a90d500",7285:"b92f705c",7380:"640bc8a0",7414:"393be207",7566:"972382ea",7587:"3ec2c3f7",7600:"2461ffa2",7706:"ce3fa444",7886:"5818c28e",7918:"17896441",7920:"1a4e3797",7937:"9a9c044b",8005:"600a9360",8015:"0e9953cd",8342:"eb3b0997",8402:"3c835dee",8561:"07f0ce13",8597:"f4a6e698",8718:"31e90f3c",8784:"35a5de3c",8835:"36ea7a08",8844:"b46ab14b",8853:"c296437a",8860:"71cf7fe6",8888:"ee5d850a",8915:"f9cc156b",9243:"40974919",9317:"f5f07875",9514:"1be78505",9594:"507542a3",9596:"88eaec5a",9609:"58160c0b",9617:"d83b78fc",9623:"904d61ef",9822:"fe0957ee"}[e]||e)+"."+{53:"d76597f4",112:"358a028d",229:"382b9496",340:"75523673",396:"e41dcf26",515:"d6fdf9a0",599:"ef01a5ad",674:"a3276773",713:"e8404ec1",742:"d68d210e",907:"df948777",975:"d95e9177",1083:"dc758238",1273:"c177fe37",1444:"8e098be3",1529:"cb77c953",1533:"74bc8988",1964:"bc80b38a",2331:"12ef5623",2387:"cf729afe",2429:"7d9140aa",2942:"7e9562fc",3085:"fabb506c",3206:"697ea5cb",3237:"bb60de38",3628:"e87e1188",3672:"2621ec01",3775:"c0c9431f",3821:"0e4bb161",3909:"ab34b154",3945:"fd5212eb",3996:"b79f756c",4003:"cb5cd157",4014:"2b277921",4096:"c85e22b7",4244:"1e2d58c9",4281:"fbd5783e",4343:"e12f7ce7",4357:"c9ab8a8e",4471:"bf33ef73",4490:"d10e768c",4519:"5753c5cd",4586:"b8268e5c",4628:"9c631359",4729:"2a013c27",4745:"e8758441",4796:"39c95442",4992:"1b73fe9a",5097:"a786479b",5114:"ffa26b77",5324:"d436de2e",5542:"f2ed3507",5551:"18262bd8",5643:"b5a32572",5720:"be106e3e",5851:"ad0f3e8d",5906:"9d01f089",5957:"4fb6e613",6126:"c43c04dc",6230:"7f7fb7ca",6455:"426e997b",6547:"6bff09cc",6552:"cde86692",6780:"ba84af4e",6849:"6dca875c",6860:"c82e4e25",6945:"d18f3d89",7029:"96f14d38",7107:"54d240ef",7251:"9ebcbca9",7271:"5d70da37",7285:"f7bd038b",7380:"2f6a629a",7414:"20dae7da",7566:"391f2ca7",7587:"6f37a44b",7600:"43c28611",7706:"62a49085",7886:"56d86c2e",7918:"156729cb",7920:"8a952348",7937:"9da8e8a6",8005:"0b984638",8015:"6d25c537",8342:"47b0e1a4",8402:"63cab2ea",8561:"4aefae82",8597:"891ffbff",8718:"a0004b49",8784:"cc424d0a",8835:"b650668e",8844:"0b23475f",8853:"7dc8f3c7",8860:"7dc81586",8888:"28a37eb6",8915:"be939da2",9169:"36534697",9243:"a133cd88",9317:"56314c09",9514:"bfe07248",9594:"e5fff5b5",9596:"0ba04755",9609:"0078e71d",9617:"4bd95169",9623:"107093cb",9822:"7fb3f346"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),f={},d="docs-v-2:",r.l=(e,a,c,b)=>{if(f[e])f[e].push(a);else{var t,o;if(void 0!==c)for(var n=document.getElementsByTagName("script"),i=0;i<n.length;i++){var l=n[i];if(l.getAttribute("src")==e||l.getAttribute("data-webpack")==d+c){t=l;break}}t||(o=!0,(t=document.createElement("script")).charset="utf-8",t.timeout=120,r.nc&&t.setAttribute("nonce",r.nc),t.setAttribute("data-webpack",d+c),t.src=e),f[e]=[a];var u=(a,c)=>{t.onerror=t.onload=null,clearTimeout(s);var d=f[e];if(delete f[e],t.parentNode&&t.parentNode.removeChild(t),d&&d.forEach((e=>e(c))),a)return a(c)},s=setTimeout(u.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=u.bind(null,t.onerror),t.onload=u.bind(null,t.onload),o&&document.head.appendChild(t)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),r.p="/",r.gca=function(e){return e={17896441:"7918",40974919:"9243",67158350:"674","935f2afb":"53",afef705c:"112","25f17725":"229","070b53d1":"340","0ae8b3d4":"396","53bb5fc4":"515","3c585fdb":"599",dd0670d3:"742",c1424005:"907",bd23e567:"1083","69a4ab96":"1444","6edc47f3":"1533","5e15fec9":"1964","19682bb8":"2331",d5417e33:"2429",eb23a929:"2942","1f391b9e":"3085",f8409a7e:"3206","1df93b7f":"3237",fa1a3aa0:"3628",cf6ffe2f:"3672","496bf018":"3775","21b4b958":"3821",cd90435d:"3909",a309f86e:"3945","9791fd42":"3996","6432bc55":"4003","5e50ba72":"4014",c76f729d:"4096","4cc2c078":"4244","1c734f75":"4281","18cf5ace":"4343","262418cd":"4490","2c412ea7":"4519",dc3fdd24:"4586","1ce51947":"4628","0c21af39":"4729","30ec1363":"4745","471df853":"4796",dc737160:"4992",a584ba2a:"5097","5ea65e65":"5114",a9e1a7f6:"5324","729f57ad":"5542",da60bc8f:"5551","30334fcd":"5643","30256b0d":"5720","8660bbc8":"5851",e7c796a6:"5906",e0a8f778:"6126","2bafca50":"6230","4e664dc4":"6455","1c42a294":"6547","6948bca1":"6552","57b59cd4":"6849",dbb131dd:"6860",d76e6194:"7107","9d6fd8ea":"7251","6a90d500":"7271",b92f705c:"7285","640bc8a0":"7380","393be207":"7414","972382ea":"7566","3ec2c3f7":"7587","2461ffa2":"7600",ce3fa444:"7706","5818c28e":"7886","1a4e3797":"7920","9a9c044b":"7937","600a9360":"8005","0e9953cd":"8015",eb3b0997:"8342","3c835dee":"8402","07f0ce13":"8561",f4a6e698:"8597","31e90f3c":"8718","35a5de3c":"8784","36ea7a08":"8835",b46ab14b:"8844",c296437a:"8853","71cf7fe6":"8860",ee5d850a:"8888",f9cc156b:"8915",f5f07875:"9317","1be78505":"9514","507542a3":"9594","88eaec5a":"9596","58160c0b":"9609",d83b78fc:"9617","904d61ef":"9623",fe0957ee:"9822"}[e]||e,r.p+r.u(e)},(()=>{var e={1303:0,532:0};r.f.j=(a,c)=>{var f=r.o(e,a)?e[a]:void 0;if(0!==f)if(f)c.push(f[2]);else if(/^(1303|532)$/.test(a))e[a]=0;else{var d=new Promise(((c,d)=>f=e[a]=[c,d]));c.push(f[2]=d);var b=r.p+r.u(a),t=new Error;r.l(b,(c=>{if(r.o(e,a)&&(0!==(f=e[a])&&(e[a]=void 0),f)){var d=c&&("load"===c.type?"missing":c.type),b=c&&c.target&&c.target.src;t.message="Loading chunk "+a+" failed.\n("+d+": "+b+")",t.name="ChunkLoadError",t.type=d,t.request=b,f[1](t)}}),"chunk-"+a,a)}},r.O.j=a=>0===e[a];var a=(a,c)=>{var f,d,b=c[0],t=c[1],o=c[2],n=0;if(b.some((a=>0!==e[a]))){for(f in t)r.o(t,f)&&(r.m[f]=t[f]);if(o)var i=o(r)}for(a&&a(c);n<b.length;n++)d=b[n],r.o(e,d)&&e[d]&&e[d][0](),e[d]=0;return r.O(i)},c=self.webpackChunkdocs_v_2=self.webpackChunkdocs_v_2||[];c.forEach(a.bind(null,0)),c.push=a.bind(null,c.push.bind(c))})()})();
\ No newline at end of file
diff --git a/community/index.html b/community/index.html
index 5232fbe..90882be 100644
--- a/community/index.html
+++ b/community/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -45,7 +45,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/api/index.html b/docs/api/index.html
index 7090227..08378d2 100644
--- a/docs/api/index.html
+++ b/docs/api/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -48,7 +48,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/contributing/contributing-page/index.html b/docs/contributing/contributing-page/index.html
index bf29c8a..3622aa5 100644
--- a/docs/contributing/contributing-page/index.html
+++ b/docs/contributing/contributing-page/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -47,7 +47,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/contributing/conventions-and-typing/index.html b/docs/contributing/conventions-and-typing/index.html
index 56085e0..4d176e2 100644
--- a/docs/contributing/conventions-and-typing/index.html
+++ b/docs/contributing/conventions-and-typing/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -49,7 +49,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/contributing/creating-viz-plugins/index.html b/docs/contributing/creating-viz-plugins/index.html
index c0f5e9c..eee4e20 100644
--- a/docs/contributing/creating-viz-plugins/index.html
+++ b/docs/contributing/creating-viz-plugins/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -61,7 +61,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/contributing/hooks-and-linting/index.html b/docs/contributing/hooks-and-linting/index.html
index 31197e9..d27413e 100644
--- a/docs/contributing/hooks-and-linting/index.html
+++ b/docs/contributing/hooks-and-linting/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -46,7 +46,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/contributing/local-backend/index.html b/docs/contributing/local-backend/index.html
index 30f3a86..d38cb40 100644
--- a/docs/contributing/local-backend/index.html
+++ b/docs/contributing/local-backend/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -48,7 +48,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/contributing/pull-request-guidelines/index.html b/docs/contributing/pull-request-guidelines/index.html
index ecf36df..0d83dab 100644
--- a/docs/contributing/pull-request-guidelines/index.html
+++ b/docs/contributing/pull-request-guidelines/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -45,7 +45,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/contributing/style-guide/index.html b/docs/contributing/style-guide/index.html
index b10c79d..2fb25a8 100644
--- a/docs/contributing/style-guide/index.html
+++ b/docs/contributing/style-guide/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -48,7 +48,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/contributing/testing-locally/index.html b/docs/contributing/testing-locally/index.html
index c749465..a9b0b88 100644
--- a/docs/contributing/testing-locally/index.html
+++ b/docs/contributing/testing-locally/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -52,7 +52,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/contributing/translations/index.html b/docs/contributing/translations/index.html
index c996f56..0284eb5 100644
--- a/docs/contributing/translations/index.html
+++ b/docs/contributing/translations/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -76,7 +76,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/contributing/types-of-contributions/index.html b/docs/contributing/types-of-contributions/index.html
index 8b6fde3..c06131d 100644
--- a/docs/contributing/types-of-contributions/index.html
+++ b/docs/contributing/types-of-contributions/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -56,7 +56,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/creating-charts-dashboards/creating-your-first-dashboard/index.html b/docs/creating-charts-dashboards/creating-your-first-dashboard/index.html
index a2164b2..1fead14 100644
--- a/docs/creating-charts-dashboards/creating-your-first-dashboard/index.html
+++ b/docs/creating-charts-dashboards/creating-your-first-dashboard/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -88,7 +88,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/creating-charts-dashboards/exploring-data/index.html b/docs/creating-charts-dashboards/exploring-data/index.html
index 2e053ad..1c237d9 100644
--- a/docs/creating-charts-dashboards/exploring-data/index.html
+++ b/docs/creating-charts-dashboards/exploring-data/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -150,7 +150,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/ascend/index.html b/docs/databases/ascend/index.html
index d8759bd..adaf526 100644
--- a/docs/databases/ascend/index.html
+++ b/docs/databases/ascend/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -45,7 +45,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/athena/index.html b/docs/databases/athena/index.html
index 28cedb8..e02e6a9 100644
--- a/docs/databases/athena/index.html
+++ b/docs/databases/athena/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -47,7 +47,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/bigquery/index.html b/docs/databases/bigquery/index.html
index 1ab5fb6..ded770e 100644
--- a/docs/databases/bigquery/index.html
+++ b/docs/databases/bigquery/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -52,7 +52,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/clickhouse/index.html b/docs/databases/clickhouse/index.html
index dd425c3..2e8b569 100644
--- a/docs/databases/clickhouse/index.html
+++ b/docs/databases/clickhouse/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -47,7 +47,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/cockroachdb/index.html b/docs/databases/cockroachdb/index.html
index b22a36a..42b6f2a 100644
--- a/docs/databases/cockroachdb/index.html
+++ b/docs/databases/cockroachdb/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -46,7 +46,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/cratedb/index.html b/docs/databases/cratedb/index.html
index 7d5daad..0bc71ea 100644
--- a/docs/databases/cratedb/index.html
+++ b/docs/databases/cratedb/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -49,7 +49,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/databricks/index.html b/docs/databases/databricks/index.html
index e3beaff..f9ca7f9 100644
--- a/docs/databases/databricks/index.html
+++ b/docs/databases/databricks/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -45,7 +45,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/db-connection-ui/index.html b/docs/databases/db-connection-ui/index.html
index 3fc2397..324a953 100644
--- a/docs/databases/db-connection-ui/index.html
+++ b/docs/databases/db-connection-ui/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -45,7 +45,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/docker-add-drivers/index.html b/docs/databases/docker-add-drivers/index.html
index d9d53e7..409414e 100644
--- a/docs/databases/docker-add-drivers/index.html
+++ b/docs/databases/docker-add-drivers/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -60,7 +60,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/dremio/index.html b/docs/databases/dremio/index.html
index 6b5253f..e5c9091 100644
--- a/docs/databases/dremio/index.html
+++ b/docs/databases/dremio/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -47,7 +47,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/drill/index.html b/docs/databases/drill/index.html
index c2761c0..3ae1765 100644
--- a/docs/databases/drill/index.html
+++ b/docs/databases/drill/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -52,7 +52,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/druid/index.html b/docs/databases/druid/index.html
index 3eed204..1fa45dc 100644
--- a/docs/databases/druid/index.html
+++ b/docs/databases/druid/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -58,7 +58,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/dynamodb/index.html b/docs/databases/dynamodb/index.html
index f9dc747..5479aa1 100644
--- a/docs/databases/dynamodb/index.html
+++ b/docs/databases/dynamodb/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -45,7 +45,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/elasticsearch/index.html b/docs/databases/elasticsearch/index.html
index e27a2d7..dcddad9 100644
--- a/docs/databases/elasticsearch/index.html
+++ b/docs/databases/elasticsearch/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -52,7 +52,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/exasol/index.html b/docs/databases/exasol/index.html
index f8be6c4..cc0ac34 100644
--- a/docs/databases/exasol/index.html
+++ b/docs/databases/exasol/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -46,7 +46,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/extra-settings/index.html b/docs/databases/extra-settings/index.html
index ffd402b..e8fb1ef 100644
--- a/docs/databases/extra-settings/index.html
+++ b/docs/databases/extra-settings/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -55,7 +55,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/firebird/index.html b/docs/databases/firebird/index.html
index e67801c..037eb15 100644
--- a/docs/databases/firebird/index.html
+++ b/docs/databases/firebird/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -46,7 +46,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/firebolt/index.html b/docs/databases/firebolt/index.html
index 06a4642..7cbe4ea 100644
--- a/docs/databases/firebolt/index.html
+++ b/docs/databases/firebolt/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -46,7 +46,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/google-sheets/index.html b/docs/databases/google-sheets/index.html
index bf85baa..d7beeb5 100644
--- a/docs/databases/google-sheets/index.html
+++ b/docs/databases/google-sheets/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -49,7 +49,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/hana/index.html b/docs/databases/hana/index.html
index 4b879e0..5d0e69c 100644
--- a/docs/databases/hana/index.html
+++ b/docs/databases/hana/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -45,7 +45,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/hive/index.html b/docs/databases/hive/index.html
index 7257af9..421b177 100644
--- a/docs/databases/hive/index.html
+++ b/docs/databases/hive/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -45,7 +45,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/hologres/index.html b/docs/databases/hologres/index.html
index 5d1c452..f06bfee 100644
--- a/docs/databases/hologres/index.html
+++ b/docs/databases/hologres/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -45,7 +45,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/ibm-db2/index.html b/docs/databases/ibm-db2/index.html
index 2c72eea..4a94625 100644
--- a/docs/databases/ibm-db2/index.html
+++ b/docs/databases/ibm-db2/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -46,7 +46,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/impala/index.html b/docs/databases/impala/index.html
index b00c229..09748e9 100644
--- a/docs/databases/impala/index.html
+++ b/docs/databases/impala/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -45,7 +45,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/installing-database-drivers/index.html b/docs/databases/installing-database-drivers/index.html
index 283697e..26997d8 100644
--- a/docs/databases/installing-database-drivers/index.html
+++ b/docs/databases/installing-database-drivers/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -56,7 +56,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/kusto/index.html b/docs/databases/kusto/index.html
index b60f6a5..b0797e2 100644
--- a/docs/databases/kusto/index.html
+++ b/docs/databases/kusto/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -47,7 +47,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/kylin/index.html b/docs/databases/kylin/index.html
index 8ad4230..3ce29f3 100644
--- a/docs/databases/kylin/index.html
+++ b/docs/databases/kylin/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -46,7 +46,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/meta-database/index.html b/docs/databases/meta-database/index.html
index 2066885..9d653d3 100644
--- a/docs/databases/meta-database/index.html
+++ b/docs/databases/meta-database/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -45,7 +45,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/mysql/index.html b/docs/databases/mysql/index.html
index 5c20f1a..2998fe3 100644
--- a/docs/databases/mysql/index.html
+++ b/docs/databases/mysql/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -46,7 +46,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/netezza/index.html b/docs/databases/netezza/index.html
index cde96d1..34c44c0 100644
--- a/docs/databases/netezza/index.html
+++ b/docs/databases/netezza/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -46,7 +46,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/ocient/index.html b/docs/databases/ocient/index.html
index 1358763..6a3956f 100644
--- a/docs/databases/ocient/index.html
+++ b/docs/databases/ocient/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -47,7 +47,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/oracle/index.html b/docs/databases/oracle/index.html
index fb5e4f2..b059e63 100644
--- a/docs/databases/oracle/index.html
+++ b/docs/databases/oracle/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -46,7 +46,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/pinot/index.html b/docs/databases/pinot/index.html
index c5fc8f5..114d9c3 100644
--- a/docs/databases/pinot/index.html
+++ b/docs/databases/pinot/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -45,7 +45,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/postgres/index.html b/docs/databases/postgres/index.html
index c525834..ae54cee 100644
--- a/docs/databases/postgres/index.html
+++ b/docs/databases/postgres/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -50,7 +50,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/presto/index.html b/docs/databases/presto/index.html
index ecd934a..395dd99 100644
--- a/docs/databases/presto/index.html
+++ b/docs/databases/presto/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -46,7 +46,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/redshift/index.html b/docs/databases/redshift/index.html
index eca4976..ee30024 100644
--- a/docs/databases/redshift/index.html
+++ b/docs/databases/redshift/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -46,7 +46,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/risingwave/index.html b/docs/databases/risingwave/index.html
index b55e489..02f9529 100644
--- a/docs/databases/risingwave/index.html
+++ b/docs/databases/risingwave/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -46,7 +46,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/rockset/index.html b/docs/databases/rockset/index.html
index 9c0e888..b29a533 100644
--- a/docs/databases/rockset/index.html
+++ b/docs/databases/rockset/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -46,7 +46,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/snowflake/index.html b/docs/databases/snowflake/index.html
index 931c0a3..4aa425c 100644
--- a/docs/databases/snowflake/index.html
+++ b/docs/databases/snowflake/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -55,7 +55,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/solr/index.html b/docs/databases/solr/index.html
index b62b6f4..e7a9b07 100644
--- a/docs/databases/solr/index.html
+++ b/docs/databases/solr/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -46,7 +46,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/spark-sql/index.html b/docs/databases/spark-sql/index.html
index f7a5e85..c3e5e97 100644
--- a/docs/databases/spark-sql/index.html
+++ b/docs/databases/spark-sql/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -45,7 +45,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/sql-server/index.html b/docs/databases/sql-server/index.html
index c3711c6..5512c64 100644
--- a/docs/databases/sql-server/index.html
+++ b/docs/databases/sql-server/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -45,7 +45,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/starrocks/index.html b/docs/databases/starrocks/index.html
index 267bb17..98f5cf1 100644
--- a/docs/databases/starrocks/index.html
+++ b/docs/databases/starrocks/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -46,7 +46,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/teradata/index.html b/docs/databases/teradata/index.html
index 62fec5f..26bd262 100644
--- a/docs/databases/teradata/index.html
+++ b/docs/databases/teradata/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -52,7 +52,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/timescaledb/index.html b/docs/databases/timescaledb/index.html
index faac1b5..aad68d3 100644
--- a/docs/databases/timescaledb/index.html
+++ b/docs/databases/timescaledb/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -46,7 +46,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/trino/index.html b/docs/databases/trino/index.html
index 70dd8ac..6a3b640 100644
--- a/docs/databases/trino/index.html
+++ b/docs/databases/trino/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -47,7 +47,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/vertica/index.html b/docs/databases/vertica/index.html
index a71b14c..eb5a227 100644
--- a/docs/databases/vertica/index.html
+++ b/docs/databases/vertica/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -47,7 +47,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/databases/yugabytedb/index.html b/docs/databases/yugabytedb/index.html
index c90fe8b..21873a8 100644
--- a/docs/databases/yugabytedb/index.html
+++ b/docs/databases/yugabytedb/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -47,7 +47,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/frequently-asked-questions/index.html b/docs/frequently-asked-questions/index.html
index e98def2..f692509 100644
--- a/docs/frequently-asked-questions/index.html
+++ b/docs/frequently-asked-questions/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -131,7 +131,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/installation/alerts-reports/index.html b/docs/installation/alerts-reports/index.html
index b5ad6cb..aa06548 100644
--- a/docs/installation/alerts-reports/index.html
+++ b/docs/installation/alerts-reports/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -26,7 +26,7 @@
 <div role="region" aria-label="Skip to main content"><a class="skipToContent_fXgn" href="#__docusaurus_skipToContent_fallback">Skip to main content</a></div><nav aria-label="Main" class="navbar navbar--fixed-top"><div class="navbar__inner"><div class="navbar__items"><button aria-label="Toggle navigation bar" aria-expanded="false" class="navbar__toggle clean-btn" type="button"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button><a class="navbar__brand" href="/"><div class="navbar__logo"><img src="/img/superset-logo-horiz.svg" alt="Superset Logo" class="themedImage_ToTc themedImage--light_HNdA"><img src="/img/superset-logo-horiz-dark.svg" alt="Superset Logo" class="themedImage_ToTc themedImage--dark_i4oU"></div></a><div class="navbar__item dropdown dropdown--hoverable"><a href="#" aria-haspopup="true" aria-expanded="false" role="button" class="navbar__link">Documentation</a><ul class="dropdown__menu"><li><a class="dropdown__link" href="/docs/intro">Getting Started</a></li><li><a class="dropdown__link" href="/docs/frequently-asked-questions">FAQ</a></li></ul></div><div class="navbar__item dropdown dropdown--hoverable"><a href="#" aria-haspopup="true" aria-expanded="false" role="button" class="navbar__link">Community</a><ul class="dropdown__menu"><li><a class="dropdown__link" href="/community">Resources</a></li><li><a href="https://github.com/apache/superset" target="_blank" rel="noopener noreferrer" class="dropdown__link">GitHub<svg width="12" height="12" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li><li><a href="http://bit.ly/join-superset-slack" target="_blank" rel="noopener noreferrer" class="dropdown__link">Slack<svg width="12" height="12" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li><li><a href="https://lists.apache.org/list.html?dev@superset.apache.org" target="_blank" rel="noopener noreferrer" class="dropdown__link">Mailing List<svg width="12" height="12" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li><li><a href="https://stackoverflow.com/questions/tagged/superset+apache-superset" target="_blank" rel="noopener noreferrer" class="dropdown__link">Stack Overflow<svg width="12" height="12" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li></ul></div></div><div class="navbar__items navbar__items--right"><a class="navbar__item navbar__link default-button-theme get-started-button" href="/docs/intro">Get Started</a><a href="https://github.com/apache/superset" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link github-button"></a><div class="searchBox_ZlJk"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><svg width="20" height="20" class="DocSearch-Search-Icon" viewBox="0 0 20 20"><path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"></span></button></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div id="__docusaurus_skipToContent_fallback" class="main-wrapper mainWrapper_z2l0 docsWrapper_BCFX"><button aria-label="Scroll back to top" class="clean-btn theme-back-to-top-button backToTopButton_sjWU" type="button"></button><div class="docPage__5DB"><aside class="theme-doc-sidebar-container docSidebarContainer_b6E3"><div class="sidebarViewport_Xe31"><div class="sidebar_njMd"><nav aria-label="Docs sidebar" class="menu thin-scrollbar menu_SIkG"><ul class="theme-doc-sidebar-menu menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/docs/intro">Introduction</a></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret menu__link--active" aria-expanded="true" href="/docs/installation/installing-superset-using-docker-compose">Installation and Configuration</a></div><ul style="display:block;overflow:visible;height:auto" class="menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/installation/installing-superset-using-docker-compose">Installing Locally Using Docker Compose</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/installation/installing-superset-from-scratch">Installing From Scratch</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/installation/running-on-kubernetes">Installing on Kubernetes</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/installation/configuring-superset">Configuring Superset</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/installation/networking-settings">Additional Networking Settings</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/installation/cache">Caching</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/installation/event-logging">Event Logging</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/installation/upgrading-superset">Upgrading Superset</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/installation/async-queries-celery">Async Queries via Celery</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link menu__link--active" aria-current="page" tabindex="0" href="/docs/installation/alerts-reports">Alerts and Reports</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/installation/sql-templating">SQL Templating</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/installation/setup-ssh-tunneling">Setup SSH Tunneling</a></li></ul></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" aria-expanded="false" href="/docs/databases/installing-database-drivers">Connecting to Databases</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" aria-expanded="false" href="/docs/creating-charts-dashboards/creating-your-first-dashboard">Creating Charts and Dashboards</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" aria-expanded="false" href="/docs/miscellaneous/country-map-tools">Miscellaneous</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" aria-expanded="false" href="/docs/contributing/contributing-page">Contributing</a></div></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/docs/frequently-asked-questions">Frequently Asked Questions</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/docs/api">API</a></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist" aria-expanded="false" href="/docs/security/">Security</a><button aria-label="Toggle the collapsible sidebar category &#x27;Security&#x27;" type="button" class="clean-btn menu__caret"></button></div></li></ul></nav></div></div></aside><main class="docMainContainer_gTbr"><div class="container padding-top--md padding-bottom--lg"><div class="row"><div class="col docItemCol_VOVn"><div class="docItemContainer_Djhp"><article><nav class="theme-doc-breadcrumbs breadcrumbsContainer_Z_bl" aria-label="Breadcrumbs"><ul class="breadcrumbs" itemscope="" itemtype="https://schema.org/BreadcrumbList"><li class="breadcrumbs__item"><a aria-label="Home page" class="breadcrumbs__link" href="/"><svg viewBox="0 0 24 24" class="breadcrumbHomeIcon_YNFT"><path d="M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z" fill="currentColor"></path></svg></a></li><li class="breadcrumbs__item"><span class="breadcrumbs__link">Installation and Configuration</span><meta itemprop="position" content="1"></li><li itemscope="" itemprop="itemListElement" itemtype="https://schema.org/ListItem" class="breadcrumbs__item breadcrumbs__item--active"><span class="breadcrumbs__link" itemprop="name">Alerts and Reports</span><meta itemprop="position" content="2"></li></ul></nav><div class="tocCollapsible_ETCw theme-doc-toc-mobile tocMobile_ITEo"><button type="button" class="clean-btn tocCollapsibleButton_TO0P">On this page</button></div><div class="theme-doc-markdown markdown"><h2 class="anchor anchorWithStickyNavbar_LWe7" id="alerts-and-reports">Alerts and Reports<a href="#alerts-and-reports" class="hash-link" aria-label="Direct link to Alerts and Reports" title="Direct link to Alerts and Reports">​</a></h2><p><em>This covers versions 1.0.1 to current.</em></p><p>Users can configure automated alerts and reports to send dashboards or charts to an email recipient or Slack channel.</p><ul><li>Alerts are sent when a SQL condition is reached</li><li>Reports are sent on a schedule</li></ul><p>Alerts and reports are disabled by default. To turn them on, you need to do some setup, described here.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="requirements">Requirements<a href="#requirements" class="hash-link" aria-label="Direct link to Requirements" title="Direct link to Requirements">​</a></h3><h4 class="anchor anchorWithStickyNavbar_LWe7" id="commons">Commons<a href="#commons" class="hash-link" aria-label="Direct link to Commons" title="Direct link to Commons">​</a></h4><h5 class="anchor anchorWithStickyNavbar_LWe7" id="in-your-superset_configpy-or-superset_config_dockerpy">In your <code>superset_config.py</code> or <code>superset_config_docker.py</code><a href="#in-your-superset_configpy-or-superset_config_dockerpy" class="hash-link" aria-label="Direct link to in-your-superset_configpy-or-superset_config_dockerpy" title="Direct link to in-your-superset_configpy-or-superset_config_dockerpy">​</a></h5><ul><li><code>&quot;ALERT_REPORTS&quot;</code> <a href="https://superset.apache.org/docs/installation/configuring-superset#feature-flags" target="_blank" rel="noopener noreferrer">feature flag</a> must be turned to True.</li><li><code>beat_schedule</code> in CeleryConfig must contain schedule for <code>reports.scheduler</code>.</li><li>At least one of those must be configured, depending on what you want to use:<ul><li>emails: <code>SMTP_*</code> settings</li><li>Slack messages: <code>SLACK_API_TOKEN</code></li></ul></li></ul><h6 class="anchor anchorWithStickyNavbar_LWe7" id="disable-dry-run-mode">Disable dry-run mode<a href="#disable-dry-run-mode" class="hash-link" aria-label="Direct link to Disable dry-run mode" title="Direct link to Disable dry-run mode">​</a></h6><p>Screenshots will be taken but no messages actually sent as long as <code>ALERT_REPORTS_NOTIFICATION_DRY_RUN = True</code>, its default value in <code>docker/pythonpath_dev/superset_config.py</code>.  To disable dry-run mode and start receiving email/Slack notifications, set <code>ALERT_REPORTS_NOTIFICATION_DRY_RUN</code> to <code>False</code> in <a href="https://github.com/apache/superset/blob/master/docker/pythonpath_dev/superset_config.py" target="_blank" rel="noopener noreferrer">superset config</a>.</p><h5 class="anchor anchorWithStickyNavbar_LWe7" id="in-your-dockerfile">In your <code>Dockerfile</code><a href="#in-your-dockerfile" class="hash-link" aria-label="Direct link to in-your-dockerfile" title="Direct link to in-your-dockerfile">​</a></h5><ul><li>You must install a headless browser, for taking screenshots of the charts and dashboards. Only Firefox and Chrome are currently supported.<blockquote><p>If you choose Chrome, you must also change the value of <code>WEBDRIVER_TYPE</code> to <code>&quot;chrome&quot;</code> in your <code>superset_config.py</code>.</p></blockquote></li></ul><p>Note: All the components required (Firefox headless browser, Redis, Postgres db, celery worker and celery beat) are present in the <em>dev</em> docker image if you are following <a href="https://superset.apache.org/docs/installation/installing-superset-using-docker-compose/" target="_blank" rel="noopener noreferrer">Installing Superset Locally</a>.
 All you need to do is add the required config variables described in this guide (See <code>Detailed Config</code>).</p><p>If you are running a non-dev docker image, e.g., a stable release like <code>apache/superset:2.0.1</code>, that image does not include a headless browser.  Only the <code>superset_worker</code> container needs this headless browser to browse to the target chart or dashboard.
 You can either install and configure the headless browser - see &quot;Custom Dockerfile&quot; section below - or when deploying via <code>docker compose</code>, modify your <code>docker-compose.yml</code> file to use a dev image for the worker container and a stable release image for the <code>superset_app</code> container.</p><p><em>Note</em>: In this context, a &quot;dev image&quot; is the same application software as its corresponding non-dev image, just bundled with additional tools.  So an image like <code>2.0.1-dev</code> is identical to <code>2.0.1</code> when it comes to stability, functionality, and running in production.  The actual &quot;in-development&quot; versions of Superset - cutting-edge and unstable - are not tagged with version numbers on Docker Hub and will display version <code>0.0.0-dev</code> within the Superset UI.</p><h4 class="anchor anchorWithStickyNavbar_LWe7" id="slack-integration">Slack integration<a href="#slack-integration" class="hash-link" aria-label="Direct link to Slack integration" title="Direct link to Slack integration">​</a></h4><p>To send alerts and reports to Slack channels, you need to create a new Slack Application on your workspace.</p><ol><li>Connect to your Slack workspace, then head to <a href="https://api.slack.com/apps" target="_blank" rel="noopener noreferrer">https://api.slack.com/apps</a>.</li><li>Create a new app.</li><li>Go to &quot;OAuth &amp; Permissions&quot; section, and give the following scopes to your app:<ul><li><code>incoming-webhook</code></li><li><code>files:write</code></li><li><code>chat:write</code></li></ul></li><li>At the top of the &quot;OAuth and Permissions&quot; section, click &quot;install to workspace&quot;.</li><li>Select a default channel for your app and continue.
-(You can post to any channel by inviting your Superset app into that channel).</li><li>The app should now be installed in your workspace, and a &quot;Bot User OAuth Access Token&quot; should have been created. Copy that token in the <code>SLACK_API_TOKEN</code> variable of your <code>superset_config.py</code>.</li><li>Restart the service (or run <code>superset init</code>) to pull in the new configuration.</li></ol><p>Note: when you configure an alert or a report, the Slack channel list takes channel names without the leading &#x27;#&#x27; e.g. use <code>alerts</code> instead of <code>#alerts</code>.</p><h4 class="anchor anchorWithStickyNavbar_LWe7" id="kubernetes-specific">Kubernetes-specific<a href="#kubernetes-specific" class="hash-link" aria-label="Direct link to Kubernetes-specific" title="Direct link to Kubernetes-specific">​</a></h4><ul><li>You must have a <code>celery beat</code> pod running. If you&#x27;re using the chart included in the GitHub repository under <a href="https://github.com/apache/superset/tree/master/helm/superset" target="_blank" rel="noopener noreferrer">helm/superset</a>, you need to put <code>supersetCeleryBeat.enabled = true</code> in your values override.</li><li>You can see the dedicated docs about <a href="/docs/installation/running-on-kubernetes">Kubernetes installation</a> for more generic details.</li></ul><h4 class="anchor anchorWithStickyNavbar_LWe7" id="docker-compose-specific">Docker Compose specific<a href="#docker-compose-specific" class="hash-link" aria-label="Direct link to Docker Compose specific" title="Direct link to Docker Compose specific">​</a></h4><h5 class="anchor anchorWithStickyNavbar_LWe7" id="you-must-have-in-your-docker-composeyml">You must have in your <code>docker-compose.yml</code><a href="#you-must-have-in-your-docker-composeyml" class="hash-link" aria-label="Direct link to you-must-have-in-your-docker-composeyml" title="Direct link to you-must-have-in-your-docker-composeyml">​</a></h5><ul><li>A Redis message broker</li><li>PostgreSQL DB instead of SQLlite</li><li>One or more <code>celery worker</code></li><li>A single <code>celery beat</code></li></ul><p>This process also works in a Docker swarm environment, you would just need to add <code>Deploy:</code> to the Superset, Redis and Postgres services along with your specific configs for your swarm.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="detailed-config">Detailed config<a href="#detailed-config" class="hash-link" aria-label="Direct link to Detailed config" title="Direct link to Detailed config">​</a></h3><p>The following configurations need to be added to the <code>superset_config.py</code> file. This file is loaded when the image runs, and any configurations in it will override the default configurations found in the <code>config.py</code>.</p><p>You can find documentation about each field in the default <code>config.py</code> in the GitHub repository under <a href="https://github.com/apache/superset/blob/master/superset/config.py" target="_blank" rel="noopener noreferrer">superset/config.py</a>.</p><p>You need to replace default values with your custom Redis, Slack and/or SMTP config.</p><p>Superset uses Celery beat and Celery worker(s) to send alerts and reports.</p><ul><li>The beat is the scheduler that tells the worker when to perform its tasks. This schedule is defined when you create the alert or report.</li><li>The worker will process the  tasks that need to be performed when an alert or report is fired.</li></ul><p>In the <code>CeleryConfig</code>, only the <code>beat_schedule</code> is relevant to this feature, the rest of the <code>CeleryConfig</code> can be changed for your needs.</p><div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> celery</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">schedules </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> crontab</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">FEATURE_FLAGS </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">&quot;ALERT_REPORTS&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">True</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">REDIS_HOST </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;superset_cache&quot;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">REDIS_PORT </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;6379&quot;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">CeleryConfig</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    broker_url </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&#x27;redis://%s:%s/0&#x27;</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">%</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">REDIS_HOST</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> REDIS_PORT</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    imports </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">&#x27;superset.sql_lab&#x27;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;superset.tasks&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;superset.tasks.thumbnails&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    result_backend </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&#x27;redis://%s:%s/0&#x27;</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">%</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">REDIS_HOST</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> REDIS_PORT</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    worker_prefetch_multiplier </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    task_acks_late </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">True</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    task_annotations </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">&#x27;sql_lab.get_sql_results&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">&#x27;rate_limit&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&#x27;100/s&#x27;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">&#x27;email_reports.send&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">&#x27;rate_limit&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&#x27;1/s&#x27;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">&#x27;time_limit&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">600</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">&#x27;soft_time_limit&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">600</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">&#x27;ignore_result&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    beat_schedule </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">&#x27;reports.scheduler&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">&#x27;task&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&#x27;reports.scheduler&#x27;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">&#x27;schedule&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> crontab</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">minute</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">&#x27;*&#x27;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> hour</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">&#x27;*&#x27;</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">&#x27;reports.prune_log&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">&#x27;task&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&#x27;reports.prune_log&#x27;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">&#x27;schedule&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> crontab</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">minute</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> hour</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">CELERY_CONFIG </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> CeleryConfig</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">SCREENSHOT_LOCATE_WAIT </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">100</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">SCREENSHOT_LOAD_WAIT </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">600</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># Slack configuration</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">SLACK_API_TOKEN </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;xoxb-&quot;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># Email configuration</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">SMTP_HOST </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;smtp.sendgrid.net&quot;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic"># change to your host</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">SMTP_PORT </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2525</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic"># your port, e.g. 587</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">SMTP_STARTTLS </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">True</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">SMTP_SSL_SERVER_AUTH </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">True</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic"># If your using an SMTP server with a valid certificate</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">SMTP_SSL </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">False</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">SMTP_USER </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;your_user&quot;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic"># use the empty string &quot;&quot; if using an unauthenticated SMTP server</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">SMTP_PASSWORD </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;your_password&quot;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic"># use the empty string &quot;&quot; if using an unauthenticated SMTP server</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">SMTP_MAIL_FROM </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;noreply@youremail.com&quot;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">EMAIL_REPORTS_SUBJECT_PREFIX </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;[Superset] &quot;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic"># optional - overwrites default value in config.py of &quot;[Report] &quot;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># WebDriver configuration</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># If you use Firefox, you can stick with default values</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># If you use Chrome, then add the following WEBDRIVER_TYPE and WEBDRIVER_OPTION_ARGS</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">WEBDRIVER_TYPE </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;chrome&quot;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">WEBDRIVER_OPTION_ARGS </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">&quot;--force-device-scale-factor=2.0&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">&quot;--high-dpi-support=2.0&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">&quot;--headless&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">&quot;--disable-gpu&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">&quot;--disable-dev-shm-usage&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">&quot;--no-sandbox&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">&quot;--disable-setuid-sandbox&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">&quot;--disable-extensions&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># This is for internal use, you can keep http</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">WEBDRIVER_BASEURL </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;http://superset:8088&quot;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># This is the link sent to the recipient. Change to your domain, e.g. https://superset.mydomain.com</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">WEBDRIVER_BASEURL_USER_FRIENDLY </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;http://localhost:8088&quot;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>You also need
+(You can post to any channel by inviting your Superset app into that channel).</li><li>The app should now be installed in your workspace, and a &quot;Bot User OAuth Access Token&quot; should have been created. Copy that token in the <code>SLACK_API_TOKEN</code> variable of your <code>superset_config.py</code>.</li><li>Restart the service (or run <code>superset init</code>) to pull in the new configuration.</li></ol><p>Note: when you configure an alert or a report, the Slack channel list takes channel names without the leading &#x27;#&#x27; e.g. use <code>alerts</code> instead of <code>#alerts</code>.</p><h4 class="anchor anchorWithStickyNavbar_LWe7" id="kubernetes-specific">Kubernetes-specific<a href="#kubernetes-specific" class="hash-link" aria-label="Direct link to Kubernetes-specific" title="Direct link to Kubernetes-specific">​</a></h4><ul><li>You must have a <code>celery beat</code> pod running. If you&#x27;re using the chart included in the GitHub repository under <a href="https://github.com/apache/superset/tree/master/helm/superset" target="_blank" rel="noopener noreferrer">helm/superset</a>, you need to put <code>supersetCeleryBeat.enabled = true</code> in your values override.</li><li>You can see the dedicated docs about <a href="/docs/installation/running-on-kubernetes">Kubernetes installation</a> for more generic details.</li></ul><h4 class="anchor anchorWithStickyNavbar_LWe7" id="docker-compose-specific">Docker Compose specific<a href="#docker-compose-specific" class="hash-link" aria-label="Direct link to Docker Compose specific" title="Direct link to Docker Compose specific">​</a></h4><h5 class="anchor anchorWithStickyNavbar_LWe7" id="you-must-have-in-your-docker-composeyml">You must have in your <code>docker-compose.yml</code><a href="#you-must-have-in-your-docker-composeyml" class="hash-link" aria-label="Direct link to you-must-have-in-your-docker-composeyml" title="Direct link to you-must-have-in-your-docker-composeyml">​</a></h5><ul><li>A Redis message broker</li><li>PostgreSQL DB instead of SQLlite</li><li>One or more <code>celery worker</code></li><li>A single <code>celery beat</code></li></ul><p>This process also works in a Docker swarm environment, you would just need to add <code>Deploy:</code> to the Superset, Redis and Postgres services along with your specific configs for your swarm.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="detailed-config">Detailed config<a href="#detailed-config" class="hash-link" aria-label="Direct link to Detailed config" title="Direct link to Detailed config">​</a></h3><p>The following configurations need to be added to the <code>superset_config.py</code> file. This file is loaded when the image runs, and any configurations in it will override the default configurations found in the <code>config.py</code>.</p><p>You can find documentation about each field in the default <code>config.py</code> in the GitHub repository under <a href="https://github.com/apache/superset/blob/master/superset/config.py" target="_blank" rel="noopener noreferrer">superset/config.py</a>.</p><p>You need to replace default values with your custom Redis, Slack and/or SMTP config.</p><p>Superset uses Celery beat and Celery worker(s) to send alerts and reports.</p><ul><li>The beat is the scheduler that tells the worker when to perform its tasks. This schedule is defined when you create the alert or report.</li><li>The worker will process the  tasks that need to be performed when an alert or report is fired.</li></ul><p>In the <code>CeleryConfig</code>, only the <code>beat_schedule</code> is relevant to this feature, the rest of the <code>CeleryConfig</code> can be changed for your needs.</p><div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> celery</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">schedules </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> crontab</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">FEATURE_FLAGS </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">&quot;ALERT_REPORTS&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">True</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">REDIS_HOST </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;superset_cache&quot;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">REDIS_PORT </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;6379&quot;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">CeleryConfig</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    broker_url </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string-interpolation string" style="color:#e3116c">f&quot;redis://</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">REDIS_HOST</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">:</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">REDIS_PORT</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">/0&quot;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    imports </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">&quot;superset.sql_lab&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">&quot;superset.tasks.scheduler&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    result_backend </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string-interpolation string" style="color:#e3116c">f&quot;redis://</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">REDIS_HOST</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">:</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">REDIS_PORT</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">/0&quot;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    worker_prefetch_multiplier </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    task_acks_late </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">True</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    task_annotations </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">&quot;sql_lab.get_sql_results&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">&quot;rate_limit&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;100/s&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    beat_schedule </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">&quot;reports.scheduler&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">&quot;task&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;reports.scheduler&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">&quot;schedule&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> crontab</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">minute</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">&quot;*&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> hour</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">&quot;*&quot;</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">&quot;reports.prune_log&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">&quot;task&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;reports.prune_log&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">&quot;schedule&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> crontab</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">minute</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> hour</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">CELERY_CONFIG </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> CeleryConfig</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">SCREENSHOT_LOCATE_WAIT </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">100</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">SCREENSHOT_LOAD_WAIT </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">600</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># Slack configuration</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">SLACK_API_TOKEN </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;xoxb-&quot;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># Email configuration</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">SMTP_HOST </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;smtp.sendgrid.net&quot;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic"># change to your host</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">SMTP_PORT </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2525</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic"># your port, e.g. 587</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">SMTP_STARTTLS </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">True</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">SMTP_SSL_SERVER_AUTH </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">True</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic"># If your using an SMTP server with a valid certificate</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">SMTP_SSL </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">False</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">SMTP_USER </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;your_user&quot;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic"># use the empty string &quot;&quot; if using an unauthenticated SMTP server</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">SMTP_PASSWORD </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;your_password&quot;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic"># use the empty string &quot;&quot; if using an unauthenticated SMTP server</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">SMTP_MAIL_FROM </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;noreply@youremail.com&quot;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">EMAIL_REPORTS_SUBJECT_PREFIX </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;[Superset] &quot;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic"># optional - overwrites default value in config.py of &quot;[Report] &quot;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># WebDriver configuration</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># If you use Firefox, you can stick with default values</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># If you use Chrome, then add the following WEBDRIVER_TYPE and WEBDRIVER_OPTION_ARGS</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">WEBDRIVER_TYPE </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;chrome&quot;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">WEBDRIVER_OPTION_ARGS </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">&quot;--force-device-scale-factor=2.0&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">&quot;--high-dpi-support=2.0&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">&quot;--headless&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">&quot;--disable-gpu&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">&quot;--disable-dev-shm-usage&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">&quot;--no-sandbox&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">&quot;--disable-setuid-sandbox&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">&quot;--disable-extensions&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># This is for internal use, you can keep http</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">WEBDRIVER_BASEURL </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;http://superset:8088&quot;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># This is the link sent to the recipient. Change to your domain, e.g. https://superset.mydomain.com</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">WEBDRIVER_BASEURL_USER_FRIENDLY </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;http://localhost:8088&quot;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>You also need
 to specify on behalf of which username to render the dashboards. In general dashboards and charts
 are not accessible to unauthorized requests, that is why the worker needs to take over credentials
 of an existing user to take a snapshot.</p><p>By default, Alerts and Reports are executed as the owner of the alert/report object. To use a fixed user account,
@@ -64,7 +64,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/installation/async-queries-celery/index.html b/docs/installation/async-queries-celery/index.html
index a6f7811..3481e3b 100644
--- a/docs/installation/async-queries-celery/index.html
+++ b/docs/installation/async-queries-celery/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -27,7 +27,7 @@
 support for long running queries that execute beyond the typical web request’s timeout (30-60
 seconds), it is necessary to configure an asynchronous backend for Superset which consists of:</p><ul><li>one or many Superset workers (which is implemented as a Celery worker), and can be started with
 the <code>celery worker</code> command, run <code>celery worker --help</code> to view the related options.</li><li>a celery broker (message queue) for which we recommend using Redis or RabbitMQ</li><li>a results backend that defines where the worker will persist the query results</li></ul><p>Configuring Celery requires defining a <code>CELERY_CONFIG</code> in your <code>superset_config.py</code>. Both the worker
-and web server processes should have the same configuration.</p><div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">CeleryConfig</span><span class="token punctuation" style="color:#393A34">(</span><span class="token builtin">object</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    broker_url </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&#x27;redis://localhost:6379/0&#x27;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    imports </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">&#x27;superset.sql_lab&#x27;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">&#x27;superset.tasks&#x27;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    result_backend </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&#x27;redis://localhost:6379/0&#x27;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    worker_log_level </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&#x27;DEBUG&#x27;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    worker_prefetch_multiplier </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    task_acks_late </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">True</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    task_annotations </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">&#x27;sql_lab.get_sql_results&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">&#x27;rate_limit&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&#x27;100/s&#x27;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">&#x27;email_reports.send&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">&#x27;rate_limit&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&#x27;1/s&#x27;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">&#x27;time_limit&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">120</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">&#x27;soft_time_limit&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">150</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">&#x27;ignore_result&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    beat_schedule </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">&#x27;email_reports.schedule_hourly&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">&#x27;task&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&#x27;email_reports.schedule_hourly&#x27;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">&#x27;schedule&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> crontab</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">minute</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> hour</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">&#x27;*&#x27;</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">CELERY_CONFIG </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> CeleryConfig</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>To start a Celery worker to leverage the configuration, run the following command:</p><div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">celery --app=superset.tasks.celery_app:app worker --pool=prefork -O fair -c 4</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>To start a job which schedules periodic background jobs, run the following command:</p><div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">celery --app=superset.tasks.celery_app:app beat</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>To setup a result backend, you need to pass an instance of a derivative of from
+and web server processes should have the same configuration.</p><div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">CeleryConfig</span><span class="token punctuation" style="color:#393A34">(</span><span class="token builtin">object</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    broker_url </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;redis://localhost:6379/0&quot;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    imports </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">&quot;superset.sql_lab&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">&quot;superset.tasks.scheduler&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    result_backend </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;redis://localhost:6379/0&quot;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    worker_prefetch_multiplier </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    task_acks_late </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">True</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    task_annotations </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">&quot;sql_lab.get_sql_results&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">&quot;rate_limit&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;100/s&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">CELERY_CONFIG </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> CeleryConfig</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>To start a Celery worker to leverage the configuration, run the following command:</p><div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">celery --app=superset.tasks.celery_app:app worker --pool=prefork -O fair -c 4</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>To start a job which schedules periodic background jobs, run the following command:</p><div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">celery --app=superset.tasks.celery_app:app beat</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>To setup a result backend, you need to pass an instance of a derivative of from
 from flask_caching.backends.base import BaseCache to the RESULTS_BACKEND configuration key in your superset_config.py. You can
 use Memcached, Redis, S3 (<a href="https://pypi.python.org/pypi/s3werkzeugcache" target="_blank" rel="noopener noreferrer">https://pypi.python.org/pypi/s3werkzeugcache</a>), memory or the file system
 (in a single server-type setup or for testing), or to write your own caching interface. Your
@@ -61,7 +61,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/installation/cache/index.html b/docs/installation/cache/index.html
index eb71179..f25a013 100644
--- a/docs/installation/cache/index.html
+++ b/docs/installation/cache/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -39,7 +39,7 @@
 <code>RESULTS_BACKEND</code>.</p><p>Note that this configuration does not use a flask-caching dictionary for its configuration, but
 instead requires a cachelib object.</p><p>See <a href="/docs/installation/async-queries-celery">Async Queries via Celery</a> for details.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="caching-thumbnails">Caching Thumbnails<a href="#caching-thumbnails" class="hash-link" aria-label="Direct link to Caching Thumbnails" title="Direct link to Caching Thumbnails">​</a></h3><p>This is an optional feature that can be turned on by activating it’s <a href="https://superset.apache.org/docs/installation/configuring-superset#feature-flags" target="_blank" rel="noopener noreferrer">feature flag</a> on config:</p><div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">FEATURE_FLAGS = {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    &quot;THUMBNAILS&quot;: True,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    &quot;THUMBNAILS_SQLA_LISTENERS&quot;: True,</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>By default thumbnails are rendered per user, and will fall back to the Selenium user for anonymous users.
 To always render thumbnails as a fixed user (<code>admin</code> in this example), use the following configuration:</p><div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> superset</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">tasks</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">types </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> ExecutorType</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">THUMBNAIL_SELENIUM_USER </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;admin&quot;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">THUMBNAIL_EXECUTE_AS </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">ExecutorType</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">SELENIUM</span><span class="token punctuation" style="color:#393A34">]</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>For this feature you will need a cache system and celery workers. All thumbnails are stored on cache
-and are processed asynchronously by the workers.</p><p>An example config where images are stored on S3 could be:</p><div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> flask </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> Flask</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> s3cache</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">s3cache </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> S3Cache</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">.</span><span class="token punctuation" style="color:#393A34">.</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">CeleryConfig</span><span class="token punctuation" style="color:#393A34">(</span><span class="token builtin">object</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    broker_url </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;redis://localhost:6379/0&quot;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    imports </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">&quot;superset.sql_lab&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;superset.tasks&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;superset.tasks.thumbnails&quot;</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    result_backend </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;redis://localhost:6379/0&quot;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    worker_prefetch_multiplier </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    task_acks_late </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">True</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">CELERY_CONFIG </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> CeleryConfig</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">init_thumbnail_cache</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Flask</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> S3Cache</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> S3Cache</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">&quot;bucket_name&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&#x27;thumbs_cache/&#x27;</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">THUMBNAIL_CACHE_CONFIG </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> init_thumbnail_cache</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># Async selenium thumbnail task will use the following user</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">THUMBNAIL_SELENIUM_USER </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;Admin&quot;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Using the above example cache keys for dashboards will be <code>superset_thumb__dashboard__{ID}</code>. You can
+and are processed asynchronously by the workers.</p><p>An example config where images are stored on S3 could be:</p><div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> flask </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> Flask</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> s3cache</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">s3cache </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> S3Cache</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">.</span><span class="token punctuation" style="color:#393A34">.</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">CeleryConfig</span><span class="token punctuation" style="color:#393A34">(</span><span class="token builtin">object</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    broker_url </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;redis://localhost:6379/0&quot;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    imports </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">&quot;superset.sql_lab&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">&quot;superset.tasks.thumbnails&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    result_backend </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;redis://localhost:6379/0&quot;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    worker_prefetch_multiplier </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    task_acks_late </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">True</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">CELERY_CONFIG </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> CeleryConfig</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">init_thumbnail_cache</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Flask</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> S3Cache</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> S3Cache</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">&quot;bucket_name&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&#x27;thumbs_cache/&#x27;</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">THUMBNAIL_CACHE_CONFIG </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> init_thumbnail_cache</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># Async selenium thumbnail task will use the following user</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">THUMBNAIL_SELENIUM_USER </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;Admin&quot;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Using the above example cache keys for dashboards will be <code>superset_thumb__dashboard__{ID}</code>. You can
 override the base URL for selenium using:</p><div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">WEBDRIVER_BASEURL = &quot;https://superset.company.com&quot;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Additional selenium web drive configuration can be set using <code>WEBDRIVER_CONFIGURATION</code>. You can
 implement a custom function to authenticate selenium. The default function uses the <code>flask-login</code>
 session cookie. Here&#x27;s an example of a custom function signature:</p><div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">auth_driver</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">driver</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> WebDriver</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> user</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;User&quot;</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> WebDriver</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">pass</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Then on configuration:</p><div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">WEBDRIVER_AUTH_FUNC = auth_driver</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div><footer class="theme-doc-footer docusaurus-mt-lg"><div class="theme-doc-footer-edit-meta-row row"><div class="col"><a href="https://github.com/apache/superset/tree/master/docs/docs/installation/cache.mdx" target="_blank" rel="noreferrer noopener" class="theme-edit-this-page"><svg fill="currentColor" height="20" width="20" viewBox="0 0 40 40" class="iconEdit_Z9Sw" aria-hidden="true"><g><path d="m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"></path></g></svg>Edit this page</a></div><div class="col lastUpdated_vwxv"></div></div></footer></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Docs pages"><a class="pagination-nav__link pagination-nav__link--prev" href="/docs/installation/networking-settings"><div class="pagination-nav__sublabel">Previous</div><div class="pagination-nav__label">Additional Networking Settings</div></a><a class="pagination-nav__link pagination-nav__link--next" href="/docs/installation/event-logging"><div class="pagination-nav__sublabel">Next</div><div class="pagination-nav__label">Event Logging</div></a></nav></div></div><div class="col col--3"><div class="tableOfContents_bqdL thin-scrollbar theme-doc-toc-desktop"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#caching" class="table-of-contents__link toc-highlight">Caching</a><ul><li><a href="#dependencies" class="table-of-contents__link toc-highlight">Dependencies</a></li><li><a href="#fallback-metastore-cache" class="table-of-contents__link toc-highlight">Fallback Metastore Cache</a></li><li><a href="#chart-cache-timeout" class="table-of-contents__link toc-highlight">Chart Cache Timeout</a></li><li><a href="#sql-lab-query-results" class="table-of-contents__link toc-highlight">SQL Lab Query Results</a></li><li><a href="#caching-thumbnails" class="table-of-contents__link toc-highlight">Caching Thumbnails</a></li></ul></li></ul></div></div></div></div></main></div></div><footer class="footer"><div class="container container-fluid"><div class="footer__bottom text--center"><div class="footer__copyright">
@@ -64,7 +64,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/installation/configuring-superset/index.html b/docs/installation/configuring-superset/index.html
index 73deb1b..ea2f109 100644
--- a/docs/installation/configuring-superset/index.html
+++ b/docs/installation/configuring-superset/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -98,7 +98,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/installation/event-logging/index.html b/docs/installation/event-logging/index.html
index 948c833..9768cdb 100644
--- a/docs/installation/event-logging/index.html
+++ b/docs/installation/event-logging/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -51,7 +51,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/installation/installing-superset-from-scratch/index.html b/docs/installation/installing-superset-from-scratch/index.html
index 39a0cdc..51ce408 100644
--- a/docs/installation/installing-superset-from-scratch/index.html
+++ b/docs/installation/installing-superset-from-scratch/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -56,7 +56,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/installation/installing-superset-using-docker-compose/index.html b/docs/installation/installing-superset-using-docker-compose/index.html
index ab8d5e0..4069259 100644
--- a/docs/installation/installing-superset-using-docker-compose/index.html
+++ b/docs/installation/installing-superset-using-docker-compose/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -71,7 +71,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/installation/networking-settings/index.html b/docs/installation/networking-settings/index.html
index aa2ffa8..03100d2 100644
--- a/docs/installation/networking-settings/index.html
+++ b/docs/installation/networking-settings/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -55,7 +55,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/installation/running-on-kubernetes/index.html b/docs/installation/running-on-kubernetes/index.html
index 610da13..7b5c89c 100644
--- a/docs/installation/running-on-kubernetes/index.html
+++ b/docs/installation/running-on-kubernetes/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -30,7 +30,7 @@
 dialect to be installed for each datastore you want to connect to.</p><p>See <a href="/docs/databases/installing-database-drivers">Install Database Drivers</a> for more information.</p></div></div><p>The following example installs the Big Query and Elasticsearch database drivers so that you can
 connect to those datasources in your Superset installation:</p><div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">bootstrapScript</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token scalar string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">  #!/bin/bash</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">  pip install psycopg2==2.9.6 \</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    sqlalchemy-bigquery==1.6.1 \</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    elasticsearch-dbapi==0.2.5 &amp;&amp;\</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">  if [ ! -f ~/bootstrap ]; then echo &quot;Running Superset with uid {{ .Values.runAsUser }}&quot; &gt; ~/bootstrap; fi</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h4 class="anchor anchorWithStickyNavbar_LWe7" id="superset_configpy">superset_config.py<a href="#superset_configpy" class="hash-link" aria-label="Direct link to superset_config.py" title="Direct link to superset_config.py">​</a></h4><p>The default <code>superset_config.py</code> is fairly minimal and you will very likely need to extend it. This is done by specifying one or more key/value entries in <code>configOverrides</code>, e.g.:</p><div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">configOverrides</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">my_override</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token scalar string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    # This will make sure the redirect_uri is properly computed, even with SSL offloading</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    ENABLE_PROXY_FIX = True</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    FEATURE_FLAGS = {</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">        &quot;DYNAMIC_PLUGINS&quot;: True</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    }</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Those will be evaluated as Helm templates and therefore will be able to reference other <code>values.yaml</code> variables e.g. <code>{{ .Values.ingress.hosts[0] }}</code> will resolve to your ingress external domain.</p><p>The entire <code>superset_config.py</code> will be installed as a secret, so it is safe to pass sensitive parameters directly... however it might be more readable to use secret env variables for that.</p><p>Full python files can be provided by running <code>helm upgrade --install --values my-values.yaml --set-file configOverrides.oauth=set_oauth.py</code></p><h4 class="anchor anchorWithStickyNavbar_LWe7" id="environment-variables">Environment Variables<a href="#environment-variables" class="hash-link" aria-label="Direct link to Environment Variables" title="Direct link to Environment Variables">​</a></h4><p>Those can be passed as key/values either with <code>extraEnv</code> or <code>extraSecretEnv</code> if they&#x27;re sensitive. They can then be referenced from <code>superset_config.py</code> using e.g. <code>os.environ.get(&quot;VAR&quot;)</code>.</p><div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">extraEnv</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">SMTP_HOST</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> smtp.gmail.com</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">SMTP_USER</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> user@gmail.com</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">SMTP_PORT</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;587&quot;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">SMTP_MAIL_FROM</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> user@gmail.com</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">extraSecretEnv</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">SMTP_PASSWORD</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> xxxx</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">configOverrides</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">smtp</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token scalar string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    import ast</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    SMTP_HOST = os.getenv(&quot;SMTP_HOST&quot;,&quot;localhost&quot;)</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    SMTP_STARTTLS = ast.literal_eval(os.getenv(&quot;SMTP_STARTTLS&quot;, &quot;True&quot;))</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    SMTP_SSL = ast.literal_eval(os.getenv(&quot;SMTP_SSL&quot;, &quot;False&quot;))</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    SMTP_USER = os.getenv(&quot;SMTP_USER&quot;,&quot;superset&quot;)</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    SMTP_PORT = os.getenv(&quot;SMTP_PORT&quot;,25)</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    SMTP_PASSWORD = os.getenv(&quot;SMTP_PASSWORD&quot;,&quot;superset&quot;)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h4 class="anchor anchorWithStickyNavbar_LWe7" id="system-packages">System packages<a href="#system-packages" class="hash-link" aria-label="Direct link to System packages" title="Direct link to System packages">​</a></h4><p>If new system packages are required, they can be installed before application startup by overriding the container&#x27;s <code>command</code>, e.g.:</p><div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">supersetWorker</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">command</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> /bin/sh</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">c</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token scalar string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      apt update</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      apt install -y somepackage</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      apt autoremove -yqq --purge</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      apt clean</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token comment" style="color:#999988;font-style:italic"># Run celery worker</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      . </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> .Values.configMountPath </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain">/superset_bootstrap.sh; celery </span><span class="token punctuation" style="color:#393A34">-</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">app=superset.tasks.celery_app</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">app worker</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h4 class="anchor anchorWithStickyNavbar_LWe7" id="data-sources">Data sources<a href="#data-sources" class="hash-link" aria-label="Direct link to Data sources" title="Direct link to Data sources">​</a></h4><p>Data source definitions can be automatically declared by providing key/value yaml definitions in <code>extraConfigs</code>:</p><div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">extraConfigs</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">import_datasources.yaml</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token scalar string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    databases:</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    - allow_file_upload: true</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      allow_ctas: true</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      allow_cvas: true</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      database_name: example-db</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      extra: &quot;{\r\n    \&quot;metadata_params\&quot;: {},\r\n    \&quot;engine_params\&quot;: {},\r\n    \&quot;\</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">        metadata_cache_timeout\&quot;: {},\r\n    \&quot;schemas_allowed_for_file_upload\&quot;: []\r\n\</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">        }&quot;</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      sqlalchemy_uri: example://example-db.local</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      tables: []</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Those will also be mounted as secrets and can include sensitive parameters.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="configuration-examples">Configuration Examples<a href="#configuration-examples" class="hash-link" aria-label="Direct link to Configuration Examples" title="Direct link to Configuration Examples">​</a></h3><h4 class="anchor anchorWithStickyNavbar_LWe7" id="setting-up-oauth">Setting up OAuth<a href="#setting-up-oauth" class="hash-link" aria-label="Direct link to Setting up OAuth" title="Direct link to Setting up OAuth">​</a></h4><div class="theme-admonition theme-admonition-note alert alert--secondary admonition_LlT9"><div class="admonitionHeading_tbUL"><span class="admonitionIcon_kALy"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</div><div class="admonitionContent_S0QG"><p>OAuth setup requires that the <a href="https://authlib.org/" target="_blank" rel="noopener noreferrer">authlib</a> Python library is installed. This can
 be done using <code>pip</code> by updating the <code>bootstrapScript</code>. See the <a href="#dependencies">Dependencies</a> section
-for more information.</p></div></div><div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">extraEnv</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">AUTH_DOMAIN</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> example.com</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">extraSecretEnv</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">GOOGLE_KEY</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> xxxxxxxxxxxx</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">GOOGLE_SECRET</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> xxxxxxxxxxxxxxxxxxxxxxxx</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">configOverrides</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">enable_oauth</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token scalar string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    # This will make sure the redirect_uri is properly computed, even with SSL offloading</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    ENABLE_PROXY_FIX = True</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    from flask_appbuilder.security.manager import AUTH_OAUTH</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    AUTH_TYPE = AUTH_OAUTH</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    OAUTH_PROVIDERS = </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token key atrule" style="color:#00a4db">&quot;name&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;google&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token key atrule" style="color:#00a4db">&quot;icon&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;fa-google&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token key atrule" style="color:#00a4db">&quot;token_key&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;access_token&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token key atrule" style="color:#00a4db">&quot;remote_app&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token key atrule" style="color:#00a4db">&quot;client_id&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> os.getenv(&quot;GOOGLE_KEY&quot;)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token key atrule" style="color:#00a4db">&quot;client_secret&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> os.getenv(&quot;GOOGLE_SECRET&quot;)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token key atrule" style="color:#00a4db">&quot;api_base_url&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;https://www.googleapis.com/oauth2/v2/&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token key atrule" style="color:#00a4db">&quot;client_kwargs&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token key atrule" style="color:#00a4db">&quot;scope&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;email profile&quot;</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token key atrule" style="color:#00a4db">&quot;request_token_url&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> None</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token key atrule" style="color:#00a4db">&quot;access_token_url&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;https://accounts.google.com/o/oauth2/token&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token key atrule" style="color:#00a4db">&quot;authorize_url&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;https://accounts.google.com/o/oauth2/auth&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token key atrule" style="color:#00a4db">&quot;authorize_params&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token key atrule" style="color:#00a4db">&quot;hd&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> os.getenv(&quot;AUTH_DOMAIN&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> &quot;&quot;)</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># Map Authlib roles to superset roles</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    AUTH_ROLE_ADMIN = &#x27;Admin&#x27;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    AUTH_ROLE_PUBLIC = &#x27;Public&#x27;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># Will allow user self registration, allowing to create Flask users from Authorized User</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    AUTH_USER_REGISTRATION = True</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># The default user self registration role</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    AUTH_USER_REGISTRATION_ROLE = &quot;Admin&quot;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h4 class="anchor anchorWithStickyNavbar_LWe7" id="enable-alerts-and-reports">Enable Alerts and Reports<a href="#enable-alerts-and-reports" class="hash-link" aria-label="Direct link to Enable Alerts and Reports" title="Direct link to Enable Alerts and Reports">​</a></h4><p>For this, as per the <a href="/docs/installation/email-reports">Alerts and Reports doc</a>, you will need to:</p><h5 class="anchor anchorWithStickyNavbar_LWe7" id="install-a-supported-webdriver-in-the-celery-worker">Install a supported webdriver in the Celery worker<a href="#install-a-supported-webdriver-in-the-celery-worker" class="hash-link" aria-label="Direct link to Install a supported webdriver in the Celery worker" title="Direct link to Install a supported webdriver in the Celery worker">​</a></h5><p>This is done either by using a custom image that has the webdriver pre-installed, or installing at startup time by overriding the <code>command</code>. Here&#x27;s a working example for <code>chromedriver</code>:</p><div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">supersetWorker</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">command</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> /bin/sh</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">c</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token scalar string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      # Install chrome webdriver</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      # See https://github.com/apache/superset/blob/4fa3b6c7185629b87c27fc2c0e5435d458f7b73d/docs/src/pages/docs/installation/email_reports.mdx</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      apt update</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      apt install -y --no-install-recommends ./google-chrome-stable_current_amd64.deb</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      wget https://chromedriver.storage.googleapis.com/88.0.4324.96/chromedriver_linux64.zip</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      unzip chromedriver_linux64.zip</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      chmod +x chromedriver</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      mv chromedriver /usr/bin</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      apt autoremove -yqq --purge</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      apt clean</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      rm -f google-chrome-stable_current_amd64.deb chromedriver_linux64.zip</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token comment" style="color:#999988;font-style:italic"># Run</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      . </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> .Values.configMountPath </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain">/superset_bootstrap.sh; celery </span><span class="token punctuation" style="color:#393A34">-</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">app=superset.tasks.celery_app</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">app worker</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h5 class="anchor anchorWithStickyNavbar_LWe7" id="run-the-celery-beat">Run the Celery beat<a href="#run-the-celery-beat" class="hash-link" aria-label="Direct link to Run the Celery beat" title="Direct link to Run the Celery beat">​</a></h5><p>This pod will trigger the scheduled tasks configured in the alerts and reports UI section:</p><div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">supersetCeleryBeat</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">enabled</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean important" style="color:#36acaa">true</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h5 class="anchor anchorWithStickyNavbar_LWe7" id="configure-the-appropriate-celery-jobs-and-smtpslack-settings">Configure the appropriate Celery jobs and SMTP/Slack settings<a href="#configure-the-appropriate-celery-jobs-and-smtpslack-settings" class="hash-link" aria-label="Direct link to Configure the appropriate Celery jobs and SMTP/Slack settings" title="Direct link to Configure the appropriate Celery jobs and SMTP/Slack settings">​</a></h5><div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">extraEnv</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">SMTP_HOST</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> smtp.gmail.com</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">SMTP_USER</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> user@gmail.com</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">SMTP_PORT</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;587&quot;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">SMTP_MAIL_FROM</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> user@gmail.com</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">extraSecretEnv</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">SLACK_API_TOKEN</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> xoxb</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">xxxx</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">yyyy</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">SMTP_PASSWORD</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> xxxx</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">yyyy</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">configOverrides</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">feature_flags</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token scalar string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    import ast</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    FEATURE_FLAGS = </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">&quot;ALERT_REPORTS&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean important" style="color:#36acaa">True</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    SMTP_HOST = os.getenv(&quot;SMTP_HOST&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">&quot;localhost&quot;)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    SMTP_STARTTLS = ast.literal_eval(os.getenv(&quot;SMTP_STARTTLS&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> &quot;True&quot;))</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    SMTP_SSL = ast.literal_eval(os.getenv(&quot;SMTP_SSL&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> &quot;False&quot;))</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    SMTP_USER = os.getenv(&quot;SMTP_USER&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">&quot;superset&quot;)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    SMTP_PORT = os.getenv(&quot;SMTP_PORT&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">25)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    SMTP_PASSWORD = os.getenv(&quot;SMTP_PASSWORD&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">&quot;superset&quot;)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    SMTP_MAIL_FROM = os.getenv(&quot;SMTP_MAIL_FROM&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">&quot;superset@superset.com&quot;)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    SLACK_API_TOKEN = os.getenv(&quot;SLACK_API_TOKEN&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">None)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">celery_conf</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token scalar string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    from celery.schedules import crontab</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">class CeleryConfig(object)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      broker_url = f&quot;redis</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">//</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">env(&#x27;REDIS_HOST&#x27;)</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">:</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">env(&#x27;REDIS_PORT&#x27;)</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain">/0&quot;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      imports = (&#x27;superset.sql_lab&#x27;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;superset.tasks&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;superset.tasks.thumbnails&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> )</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      result_backend = f&quot;redis</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">//</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">env(&#x27;REDIS_HOST&#x27;)</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">:</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">env(&#x27;REDIS_PORT&#x27;)</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain">/0&quot;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      task_annotations = </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">&#x27;sql_lab.get_sql_results&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token key atrule" style="color:#00a4db">&#x27;rate_limit&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&#x27;100/s&#x27;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">&#x27;email_reports.send&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token key atrule" style="color:#00a4db">&#x27;rate_limit&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&#x27;1/s&#x27;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token key atrule" style="color:#00a4db">&#x27;time_limit&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">600</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token key atrule" style="color:#00a4db">&#x27;soft_time_limit&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">600</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token key atrule" style="color:#00a4db">&#x27;ignore_result&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean important" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      beat_schedule = </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">&#x27;reports.scheduler&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token key atrule" style="color:#00a4db">&#x27;task&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&#x27;reports.scheduler&#x27;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token key atrule" style="color:#00a4db">&#x27;schedule&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> crontab(minute=&#x27;</span><span class="token important">*&#x27;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> hour=&#x27;</span><span class="token important">*&#x27;)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">&#x27;reports.prune_log&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token key atrule" style="color:#00a4db">&#x27;task&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&#x27;reports.prune_log&#x27;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token key atrule" style="color:#00a4db">&#x27;schedule&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> crontab(minute=0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> hour=0)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">&#x27;cache-warmup-hourly&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token key atrule" style="color:#00a4db">&#x27;task&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&#x27;cache-warmup&#x27;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token key atrule" style="color:#00a4db">&#x27;schedule&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> crontab(minute=&#x27;</span><span class="token important">*/30&#x27;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> hour=&#x27;</span><span class="token important">*&#x27;)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token key atrule" style="color:#00a4db">&#x27;kwargs&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                  </span><span class="token key atrule" style="color:#00a4db">&#x27;strategy_name&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&#x27;top_n_dashboards&#x27;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                  </span><span class="token key atrule" style="color:#00a4db">&#x27;top_n&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                  </span><span class="token key atrule" style="color:#00a4db">&#x27;since&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&#x27;7 days ago&#x27;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    CELERY_CONFIG = CeleryConfig</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">reports</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token scalar string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    EMAIL_PAGE_RENDER_WAIT = 60</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    WEBDRIVER_BASEURL = &quot;http://{{ template &quot;superset.fullname&quot; . }}:{{ .Values.service.port }}/&quot;</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    WEBDRIVER_BASEURL_USER_FRIENDLY = &quot;https://www.example.com/&quot;</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    WEBDRIVER_TYPE= &quot;chrome&quot;</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    WEBDRIVER_OPTION_ARGS = [</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">        &quot;--force-device-scale-factor=2.0&quot;,</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">        &quot;--high-dpi-support=2.0&quot;,</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">        &quot;--headless&quot;,</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">        &quot;--disable-gpu&quot;,</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">        &quot;--disable-dev-shm-usage&quot;,</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">        # This is required because our process runs as root (in order to install pip packages)</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">        &quot;--no-sandbox&quot;,</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">        &quot;--disable-setuid-sandbox&quot;,</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">        &quot;--disable-extensions&quot;,</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    ]</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h4 class="anchor anchorWithStickyNavbar_LWe7" id="load-the-examples-data-and-dashboards">Load the Examples data and dashboards<a href="#load-the-examples-data-and-dashboards" class="hash-link" aria-label="Direct link to Load the Examples data and dashboards" title="Direct link to Load the Examples data and dashboards">​</a></h4><p>If you are trying Superset out and want some data and dashboards to explore, you can load some examples by creating a <code>my_values.yaml</code> and deploying it as described above in the <strong>Configure your setting overrides</strong> step of the <strong>Running</strong> section.
+for more information.</p></div></div><div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">extraEnv</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">AUTH_DOMAIN</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> example.com</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">extraSecretEnv</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">GOOGLE_KEY</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> xxxxxxxxxxxx</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">GOOGLE_SECRET</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> xxxxxxxxxxxxxxxxxxxxxxxx</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">configOverrides</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">enable_oauth</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token scalar string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    # This will make sure the redirect_uri is properly computed, even with SSL offloading</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    ENABLE_PROXY_FIX = True</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    from flask_appbuilder.security.manager import AUTH_OAUTH</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    AUTH_TYPE = AUTH_OAUTH</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    OAUTH_PROVIDERS = </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token key atrule" style="color:#00a4db">&quot;name&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;google&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token key atrule" style="color:#00a4db">&quot;icon&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;fa-google&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token key atrule" style="color:#00a4db">&quot;token_key&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;access_token&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token key atrule" style="color:#00a4db">&quot;remote_app&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token key atrule" style="color:#00a4db">&quot;client_id&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> os.getenv(&quot;GOOGLE_KEY&quot;)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token key atrule" style="color:#00a4db">&quot;client_secret&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> os.getenv(&quot;GOOGLE_SECRET&quot;)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token key atrule" style="color:#00a4db">&quot;api_base_url&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;https://www.googleapis.com/oauth2/v2/&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token key atrule" style="color:#00a4db">&quot;client_kwargs&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token key atrule" style="color:#00a4db">&quot;scope&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;email profile&quot;</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token key atrule" style="color:#00a4db">&quot;request_token_url&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> None</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token key atrule" style="color:#00a4db">&quot;access_token_url&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;https://accounts.google.com/o/oauth2/token&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token key atrule" style="color:#00a4db">&quot;authorize_url&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;https://accounts.google.com/o/oauth2/auth&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token key atrule" style="color:#00a4db">&quot;authorize_params&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token key atrule" style="color:#00a4db">&quot;hd&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> os.getenv(&quot;AUTH_DOMAIN&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> &quot;&quot;)</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># Map Authlib roles to superset roles</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    AUTH_ROLE_ADMIN = &#x27;Admin&#x27;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    AUTH_ROLE_PUBLIC = &#x27;Public&#x27;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># Will allow user self registration, allowing to create Flask users from Authorized User</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    AUTH_USER_REGISTRATION = True</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># The default user self registration role</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    AUTH_USER_REGISTRATION_ROLE = &quot;Admin&quot;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h4 class="anchor anchorWithStickyNavbar_LWe7" id="enable-alerts-and-reports">Enable Alerts and Reports<a href="#enable-alerts-and-reports" class="hash-link" aria-label="Direct link to Enable Alerts and Reports" title="Direct link to Enable Alerts and Reports">​</a></h4><p>For this, as per the <a href="/docs/installation/email-reports">Alerts and Reports doc</a>, you will need to:</p><h5 class="anchor anchorWithStickyNavbar_LWe7" id="install-a-supported-webdriver-in-the-celery-worker">Install a supported webdriver in the Celery worker<a href="#install-a-supported-webdriver-in-the-celery-worker" class="hash-link" aria-label="Direct link to Install a supported webdriver in the Celery worker" title="Direct link to Install a supported webdriver in the Celery worker">​</a></h5><p>This is done either by using a custom image that has the webdriver pre-installed, or installing at startup time by overriding the <code>command</code>. Here&#x27;s a working example for <code>chromedriver</code>:</p><div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">supersetWorker</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">command</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> /bin/sh</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">c</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token scalar string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      # Install chrome webdriver</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      # See https://github.com/apache/superset/blob/4fa3b6c7185629b87c27fc2c0e5435d458f7b73d/docs/src/pages/docs/installation/email_reports.mdx</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      apt update</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      apt install -y --no-install-recommends ./google-chrome-stable_current_amd64.deb</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      wget https://chromedriver.storage.googleapis.com/88.0.4324.96/chromedriver_linux64.zip</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      unzip chromedriver_linux64.zip</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      chmod +x chromedriver</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      mv chromedriver /usr/bin</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      apt autoremove -yqq --purge</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      apt clean</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      rm -f google-chrome-stable_current_amd64.deb chromedriver_linux64.zip</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token comment" style="color:#999988;font-style:italic"># Run</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      . </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> .Values.configMountPath </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain">/superset_bootstrap.sh; celery </span><span class="token punctuation" style="color:#393A34">-</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">app=superset.tasks.celery_app</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">app worker</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h5 class="anchor anchorWithStickyNavbar_LWe7" id="run-the-celery-beat">Run the Celery beat<a href="#run-the-celery-beat" class="hash-link" aria-label="Direct link to Run the Celery beat" title="Direct link to Run the Celery beat">​</a></h5><p>This pod will trigger the scheduled tasks configured in the alerts and reports UI section:</p><div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">supersetCeleryBeat</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">enabled</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean important" style="color:#36acaa">true</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h5 class="anchor anchorWithStickyNavbar_LWe7" id="configure-the-appropriate-celery-jobs-and-smtpslack-settings">Configure the appropriate Celery jobs and SMTP/Slack settings<a href="#configure-the-appropriate-celery-jobs-and-smtpslack-settings" class="hash-link" aria-label="Direct link to Configure the appropriate Celery jobs and SMTP/Slack settings" title="Direct link to Configure the appropriate Celery jobs and SMTP/Slack settings">​</a></h5><div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">extraEnv</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">SMTP_HOST</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> smtp.gmail.com</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">SMTP_USER</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> user@gmail.com</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">SMTP_PORT</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;587&quot;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">SMTP_MAIL_FROM</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> user@gmail.com</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">extraSecretEnv</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">SLACK_API_TOKEN</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> xoxb</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">xxxx</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">yyyy</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">SMTP_PASSWORD</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> xxxx</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">yyyy</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">configOverrides</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">feature_flags</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token scalar string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    import ast</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    FEATURE_FLAGS = </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">&quot;ALERT_REPORTS&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean important" style="color:#36acaa">True</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    SMTP_HOST = os.getenv(&quot;SMTP_HOST&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">&quot;localhost&quot;)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    SMTP_STARTTLS = ast.literal_eval(os.getenv(&quot;SMTP_STARTTLS&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> &quot;True&quot;))</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    SMTP_SSL = ast.literal_eval(os.getenv(&quot;SMTP_SSL&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> &quot;False&quot;))</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    SMTP_USER = os.getenv(&quot;SMTP_USER&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">&quot;superset&quot;)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    SMTP_PORT = os.getenv(&quot;SMTP_PORT&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">25)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    SMTP_PASSWORD = os.getenv(&quot;SMTP_PASSWORD&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">&quot;superset&quot;)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    SMTP_MAIL_FROM = os.getenv(&quot;SMTP_MAIL_FROM&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">&quot;superset@superset.com&quot;)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    SLACK_API_TOKEN = os.getenv(&quot;SLACK_API_TOKEN&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">None)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">celery_conf</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token scalar string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    from celery.schedules import crontab</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">class CeleryConfig</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      broker_url = f&quot;redis</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">//</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">env(&#x27;REDIS_HOST&#x27;)</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">:</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">env(&#x27;REDIS_PORT&#x27;)</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain">/0&quot;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      imports = (</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          &quot;superset.sql_lab&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token string" style="color:#e3116c">&quot;superset.tasks.cache&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token string" style="color:#e3116c">&quot;superset.tasks.scheduler&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      )</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      result_backend = f&quot;redis</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">//</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">env(&#x27;REDIS_HOST&#x27;)</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">:</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">env(&#x27;REDIS_PORT&#x27;)</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain">/0&quot;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      task_annotations = </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">&quot;sql_lab.get_sql_results&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token key atrule" style="color:#00a4db">&quot;rate_limit&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;100/s&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      beat_schedule = </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">&quot;reports.scheduler&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token key atrule" style="color:#00a4db">&quot;task&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;reports.scheduler&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token key atrule" style="color:#00a4db">&quot;schedule&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> crontab(minute=&quot;</span><span class="token important">*&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> hour=&quot;</span><span class="token important">*&quot;)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">&quot;reports.prune_log&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token key atrule" style="color:#00a4db">&quot;task&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;reports.prune_log&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token key atrule" style="color:#00a4db">&#x27;schedule&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> crontab(minute=0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> hour=0)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">&#x27;cache-warmup-hourly&#x27;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token key atrule" style="color:#00a4db">&quot;task&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;cache-warmup&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token key atrule" style="color:#00a4db">&quot;schedule&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> crontab(minute=&quot;</span><span class="token important">*/30&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> hour=&quot;</span><span class="token important">*&quot;)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token key atrule" style="color:#00a4db">&quot;kwargs&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                  </span><span class="token key atrule" style="color:#00a4db">&quot;strategy_name&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;top_n_dashboards&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                  </span><span class="token key atrule" style="color:#00a4db">&quot;top_n&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                  </span><span class="token key atrule" style="color:#00a4db">&quot;since&quot;</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">&quot;7 days ago&quot;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    CELERY_CONFIG = CeleryConfig</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">reports</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token scalar string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    EMAIL_PAGE_RENDER_WAIT = 60</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    WEBDRIVER_BASEURL = &quot;http://{{ template &quot;superset.fullname&quot; . }}:{{ .Values.service.port }}/&quot;</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    WEBDRIVER_BASEURL_USER_FRIENDLY = &quot;https://www.example.com/&quot;</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    WEBDRIVER_TYPE= &quot;chrome&quot;</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    WEBDRIVER_OPTION_ARGS = [</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">        &quot;--force-device-scale-factor=2.0&quot;,</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">        &quot;--high-dpi-support=2.0&quot;,</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">        &quot;--headless&quot;,</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">        &quot;--disable-gpu&quot;,</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">        &quot;--disable-dev-shm-usage&quot;,</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">        # This is required because our process runs as root (in order to install pip packages)</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">        &quot;--no-sandbox&quot;,</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">        &quot;--disable-setuid-sandbox&quot;,</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">        &quot;--disable-extensions&quot;,</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">    ]</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h4 class="anchor anchorWithStickyNavbar_LWe7" id="load-the-examples-data-and-dashboards">Load the Examples data and dashboards<a href="#load-the-examples-data-and-dashboards" class="hash-link" aria-label="Direct link to Load the Examples data and dashboards" title="Direct link to Load the Examples data and dashboards">​</a></h4><p>If you are trying Superset out and want some data and dashboards to explore, you can load some examples by creating a <code>my_values.yaml</code> and deploying it as described above in the <strong>Configure your setting overrides</strong> step of the <strong>Running</strong> section.
 To load the examples, add the following to the <code>my_values.yaml</code> file:</p><div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">init</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">loadExamples</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean important" style="color:#36acaa">true</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div><footer class="theme-doc-footer docusaurus-mt-lg"><div class="theme-doc-footer-edit-meta-row row"><div class="col"><a href="https://github.com/apache/superset/tree/master/docs/docs/installation/running-on-kubernetes.mdx" target="_blank" rel="noreferrer noopener" class="theme-edit-this-page"><svg fill="currentColor" height="20" width="20" viewBox="0 0 40 40" class="iconEdit_Z9Sw" aria-hidden="true"><g><path d="m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"></path></g></svg>Edit this page</a></div><div class="col lastUpdated_vwxv"></div></div></footer></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Docs pages"><a class="pagination-nav__link pagination-nav__link--prev" href="/docs/installation/installing-superset-from-scratch"><div class="pagination-nav__sublabel">Previous</div><div class="pagination-nav__label">Installing From Scratch</div></a><a class="pagination-nav__link pagination-nav__link--next" href="/docs/installation/configuring-superset"><div class="pagination-nav__sublabel">Next</div><div class="pagination-nav__label">Configuring Superset</div></a></nav></div></div><div class="col col--3"><div class="tableOfContents_bqdL thin-scrollbar theme-doc-toc-desktop"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#installing-on-kubernetes" class="table-of-contents__link toc-highlight">Installing on Kubernetes</a><ul><li><a href="#prerequisites" class="table-of-contents__link toc-highlight">Prerequisites</a></li><li><a href="#running" class="table-of-contents__link toc-highlight">Running</a></li><li><a href="#important-settings" class="table-of-contents__link toc-highlight">Important settings</a></li><li><a href="#configuration-examples" class="table-of-contents__link toc-highlight">Configuration Examples</a></li></ul></li></ul></div></div></div></div></main></div></div><footer class="footer"><div class="container container-fluid"><div class="footer__bottom text--center"><div class="footer__copyright">
           <div class="footer__applitools">
             We use &nbsp;<a href="https://applitools.com/" target="_blank" rel="nofollow"><img src="/img/applitools.png" title="Applitools"></a>
@@ -53,7 +53,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/installation/setup-ssh-tunneling/index.html b/docs/installation/setup-ssh-tunneling/index.html
index 3b69ad4..496ff3c 100644
--- a/docs/installation/setup-ssh-tunneling/index.html
+++ b/docs/installation/setup-ssh-tunneling/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -45,7 +45,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/installation/sql-templating/index.html b/docs/installation/sql-templating/index.html
index aa75830..88a9d24 100644
--- a/docs/installation/sql-templating/index.html
+++ b/docs/installation/sql-templating/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -80,7 +80,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/installation/upgrading-superset/index.html b/docs/installation/upgrading-superset/index.html
index d4ee911..394aa10 100644
--- a/docs/installation/upgrading-superset/index.html
+++ b/docs/installation/upgrading-superset/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -47,7 +47,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/intro/index.html b/docs/intro/index.html
index 6a90356..c54ab9f 100644
--- a/docs/intro/index.html
+++ b/docs/intro/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -57,7 +57,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/miscellaneous/chart-params/index.html b/docs/miscellaneous/chart-params/index.html
index 2aa0519..f2e8394 100644
--- a/docs/miscellaneous/chart-params/index.html
+++ b/docs/miscellaneous/chart-params/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -45,7 +45,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/miscellaneous/country-map-tools/index.html b/docs/miscellaneous/country-map-tools/index.html
index 01b161f..901c311 100644
--- a/docs/miscellaneous/country-map-tools/index.html
+++ b/docs/miscellaneous/country-map-tools/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -51,7 +51,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/miscellaneous/importing-exporting-datasources/index.html b/docs/miscellaneous/importing-exporting-datasources/index.html
index 6989f5b..0a2845e 100644
--- a/docs/miscellaneous/importing-exporting-datasources/index.html
+++ b/docs/miscellaneous/importing-exporting-datasources/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -56,7 +56,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/miscellaneous/issue-codes/index.html b/docs/miscellaneous/issue-codes/index.html
index 36f1634..d8a09c1 100644
--- a/docs/miscellaneous/issue-codes/index.html
+++ b/docs/miscellaneous/issue-codes/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -74,7 +74,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/miscellaneous/native-filter-migration/index.html b/docs/miscellaneous/native-filter-migration/index.html
index fe1e04b..467b854 100644
--- a/docs/miscellaneous/native-filter-migration/index.html
+++ b/docs/miscellaneous/native-filter-migration/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -63,7 +63,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/miscellaneous/timezones/index.html b/docs/miscellaneous/timezones/index.html
index 5713e4d..9be33c1 100644
--- a/docs/miscellaneous/timezones/index.html
+++ b/docs/miscellaneous/timezones/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -45,7 +45,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/security/cves/index.html b/docs/security/cves/index.html
index 8d0a9dd..cc20fe4 100644
--- a/docs/security/cves/index.html
+++ b/docs/security/cves/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -45,7 +45,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/docs/security/index.html b/docs/security/index.html
index 2722377..a84e78c 100644
--- a/docs/security/index.html
+++ b/docs/security/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -144,7 +144,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/index.html b/index.html
index b90d93a..71ef4ae 100644
--- a/index.html
+++ b/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -45,7 +45,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/markdown-page/index.html b/markdown-page/index.html
index c757e95..9dcc001 100644
--- a/markdown-page/index.html
+++ b/markdown-page/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -45,7 +45,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/search/index.html b/search/index.html
index 3f87fc6..efdd340 100644
--- a/search/index.html
+++ b/search/index.html
@@ -18,7 +18,7 @@
 
 <script src="/script/matomo.js"></script>
 <script src="https://www.bugherd.com/sidebarv2.js?apikey=enilpiu7bgexxsnoqfjtxa" async></script><link rel="stylesheet" href="/assets/css/styles.f448a7ff.css">
-<link rel="preload" href="/assets/js/runtime~main.da047873.js" as="script">
+<link rel="preload" href="/assets/js/runtime~main.ac9c8adb.js" as="script">
 <link rel="preload" href="/assets/js/main.0e81f3da.js" as="script">
 </head>
 <body class="navigation-with-keyboard">
@@ -45,7 +45,7 @@
           <!-- telemetry/analytics pixel: -->
           <img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=39ae6855-95fc-4566-86e5-360d542b0a68">
           </div></div></div></footer></div>
-<script src="/assets/js/runtime~main.da047873.js"></script>
+<script src="/assets/js/runtime~main.ac9c8adb.js"></script>
 <script src="/assets/js/main.0e81f3da.js"></script>
 </body>
 </html>
\ No newline at end of file