blob: 493be7a4c3c028d8d518989d3c653e66a68a0672 [file] [log] [blame]
{"version":3,"sources":["webpack:///./src/pages/docs/installation/configuring.mdx"],"names":["_frontmatter","layoutProps","MDXLayout","DefaultLayout","MDXContent","components","props","mdxType","parentName","isMDXComponent"],"mappings":"wPAQaA,G,UAAe,S,6NAC5B,IAAMC,EAAc,CAClBD,gBAEIE,EAAYC,IACH,SAASC,EAAT,GAGZ,IAFDC,EAEC,EAFDA,WACGC,EACF,8BACD,OAAO,YAACJ,EAAD,eAAeD,EAAiBK,EAAhC,CAAuCD,WAAYA,EAAYE,QAAQ,cAG5E,iBAAQ,CACN,GAAM,wBADR,wBAGA,iBAAQ,CACN,GAAM,iBADR,iBAGA,iFAAgE,0BAAYC,WAAW,KAAvB,sBAAhE,wBACF,0BAAYA,WAAW,KAAvB,cADE,+DAEA,uBAAK,gCAAMA,WAAW,OAAU,IAA3B,y3BA0BL,0EACF,6BAAGA,WAAW,KAAQ,CAChB,KAAQ,sEADd,qEADE,kCAI2B,0BAAYA,WAAW,KAAvB,sBAJ3B,6IAMA,8BAAa,0BAAYA,WAAW,KAAvB,sBAAb,+HACsD,0BAAYA,WAAW,KAAvB,aADtD,KACiH,0BAAYA,WAAW,KAAvB,iBADjH,KACgL,0BAAYA,WAAW,KAAvB,iBADhL,UAEE,0BAAYA,WAAW,KAAvB,oBAFF,qHAIF,6BAAGA,WAAW,KAAQ,CAChB,KAAQ,mEADd,mCAJE,kDAQA,6CACA,sBACE,kBAAIA,WAAW,MAAK,0BAAYA,WAAW,MAAvB,2BAApB,wDACA,kBAAIA,WAAW,MAAK,0BAAYA,WAAW,MAAvB,cAApB,8BAEF,2JAC2B,0BAAYA,WAAW,KAAvB,wBAD3B,KAEA,uBAAK,gCAAMA,WAAW,OAAU,IAA3B,kCAEL,iBAAQ,CACN,GAAM,iCADR,iCAGA,sZAIA,uBAAK,gCAAMA,WAAW,OAAU,IAA3B,8OASL,qCAAoB,6BAAGA,WAAW,KAAQ,CACtC,KAAQ,oDADQ,0BAApB,2BAGW,kBAAIA,WAAW,KAAf,yCAA6D,0BAAYA,WAAW,MAAvB,gBAA7D,OAA8H,0BAAYA,WAAW,MAAvB,aAA9H,2CAEX,yFAAwE,0BAAYA,WAAW,KAAvB,kBAAxE,gBACF,0BAAYA,WAAW,KAAvB,6BADE,YACgF,0BAAYA,WAAW,KAAvB,sBADhF,KAEA,iBAAQ,CACN,GAAM,wCADR,wCAGA,oQAEuC,0BAAYA,WAAW,KAAvB,WAFvC,uFAIA,0DAAyC,0BAAYA,WAAW,KAAvB,qCAAzC,6BACF,0BAAYA,WAAW,KAAvB,2BADE,iCACmG,0BAAYA,WAAW,KAAvB,sBADnG,sCAGA,uHACF,0BAAYA,WAAW,KAAvB,qBADE,0EAEA,uBAAK,gCAAMA,WAAW,OAAU,IAA3B,kDAEL,iBAAQ,CACN,GAAM,+BADR,+BAGA,gOAEA,kDAAiC,6BAAGA,WAAW,KAAQ,CACnD,KAAQ,yBACP,0BAAYA,WAAW,KAAvB,YAFL,mCAGA,mEAAkD,0BAAYA,WAAW,KAAvB,sBAAlD,KACA,uBAAK,gCAAMA,WAAW,OAAU,CAC5B,UAAa,oBADZ,29CAiCL,uCAAsB,0BAAYA,WAAW,KAAvB,4BAAtB,iBAA4G,0BAAYA,WAAW,KAAvB,2BAA5G,mBACF,0BAAYA,WAAW,KAAvB,mBADE,KAEA,uBAAK,gCAAMA,WAAW,OAAU,CAC5B,UAAa,oBADZ,uxBAgBL,6EAA4D,0BAAYA,WAAW,KAAvB,sBAA5D,mBACF,0BAAYA,WAAW,KAAvB,kCADE,2CACoH,0BAAYA,WAAW,KAAvB,sBADpH,KAEA,uBAAK,gCAAMA,WAAW,OAAU,IAA3B,2HAGL,qBAAG,sBAAQA,WAAW,KAAnB,UACH,sBACE,kBAAIA,WAAW,MACb,iBAAGA,WAAW,MAAd,4BAAgD,0BAAYA,WAAW,KAAvB,iEAAhD,0GAEH,0BAAYA,WAAW,KAAvB,wDAFG,kCAIF,kBAAIA,WAAW,MACb,iBAAGA,WAAW,MAAd,6IAC8B,0BAAYA,WAAW,KAAvB,gBAD9B,KAC4F,0BAAYA,WAAW,KAAvB,oBAD5F,KAC8J,0BAAYA,WAAW,KAAvB,iBAD9J,qFAGA,mBAAKA,WAAW,MAAK,gCAAMA,WAAW,OAAU,CAC5C,UAAa,oBADI,0gBAgBzB,iBAAQ,CACN,GAAM,iBADR,iBAGA,8YAIA,0EAAyD,0BAAYA,WAAW,KAAvB,sBAAzD,KACA,uBAAK,gCAAMA,WAAW,OAAU,CAC5B,UAAa,oBADZ,4IAQL,wEAAuD,0BAAYA,WAAW,KAAvB,+BACvD,iBAAQ,CACN,GAAM,UADR,UAGA,qBAAG,6BAAGA,WAAW,KAAQ,CACrB,KAAQ,mDADT,oCAAH,0IAKA,2SAGA,4MAC+E,0BAAYA,WAAW,KAAvB,SAD/E,eAEA,uBAAK,gCAAMA,WAAW,OAAU,IAA3B,wFAML,qBAAG,sBAAQA,WAAW,KAAnB,oBACH,0FAAyE,0BAAYA,WAAW,KAAvB,sBAAzE,KACA,uBAAK,gCAAMA,WAAW,OAAU,IAA3B,8BAGL,qBAAG,sBAAQA,WAAW,KAAnB,yBACH,8XAIA,+PAGA,uBAAK,gCAAMA,WAAW,OAAU,CAC5B,UAAa,oBADZ,4GAOL,0QAEuC,0BAAYA,WAAW,KAAvB,SAFvC,eAGA,uBAAK,gCAAMA,WAAW,OAAU,CAC5B,UAAa,oBADZ,mEAML,0GACF,0BAAYA,WAAW,KAAvB,wBADE,oE,2NAMJJ,EAAWK,gBAAiB","file":"component---src-pages-docs-installation-configuring-mdx-5b0f26ca5b17478d5e2f.js","sourcesContent":["import * as React from 'react'\n /* @jsx mdx */\nimport { mdx } from '@mdx-js/react';\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\n\nimport DefaultLayout from \"/home/runner/work/superset/superset/docs/node_modules/gatsby-theme-docz/src/base/Layout.js\";\nexport const _frontmatter = {};\nconst layoutProps = {\n _frontmatter\n};\nconst MDXLayout = DefaultLayout;\nexport default function MDXContent({\n components,\n ...props\n}) {\n return <MDXLayout {...layoutProps} {...props} components={components} mdxType=\"MDXLayout\">\n\n\n <h2 {...{\n \"id\": \"configuring-superset\"\n }}>{`Configuring Superset`}</h2>\n <h3 {...{\n \"id\": \"configuration\"\n }}>{`Configuration`}</h3>\n <p>{`To configure your application, you need to create a file `}<inlineCode parentName=\"p\">{`superset_config.py`}</inlineCode>{` and add it to your\n`}<inlineCode parentName=\"p\">{`PYTHONPATH`}</inlineCode>{`. Here are some of the parameters you can set in that file:`}</p>\n <pre><code parentName=\"pre\" {...{}}>{`# Superset specific config\nROW_LIMIT = 5000\n\nSUPERSET_WEBSERVER_PORT = 8088\n\n# Flask App Builder configuration\n# Your App secret key\nSECRET_KEY = '\\\\2\\\\1thisismyscretkey\\\\1\\\\2\\\\e\\\\y\\\\y\\\\h'\n\n# The SQLAlchemy connection string to your database backend\n# This connection defines the path to the database that stores your\n# superset metadata (slices, connections, tables, dashboards, ...).\n# Note that the connection information to connect to the datasources\n# you want to explore are managed directly in the web UI\nSQLALCHEMY_DATABASE_URI = 'sqlite:////path/to/superset.db'\n\n# Flask-WTF flag for CSRF\nWTF_CSRF_ENABLED = True\n# Add endpoints that need to be exempt from CSRF protection\nWTF_CSRF_EXEMPT_LIST = []\n# A CSRF token that expires in 1 year\nWTF_CSRF_TIME_LIMIT = 60 * 60 * 24 * 365\n\n# Set this API key to enable Mapbox visualizations\nMAPBOX_API_KEY = ''\n`}</code></pre>\n <p>{`All the parameters and default values defined in\n`}<a parentName=\"p\" {...{\n \"href\": \"https://github.com/apache/superset/blob/master/superset/config.py\"\n }}>{`https://github.com/apache/superset/blob/master/superset/config.py`}</a>{`\ncan be altered in your local `}<inlineCode parentName=\"p\">{`superset_config.py`}</inlineCode>{`. Administrators will want to read through the file\nto understand what can be configured locally as well as the default values in place.`}</p>\n <p>{`Since `}<inlineCode parentName=\"p\">{`superset_config.py`}</inlineCode>{` acts as a Flask configuration module, it can be used to alter the\nsettings Flask itself, as well as Flask extensions like `}<inlineCode parentName=\"p\">{`flask-wtf`}</inlineCode>{`, `}<inlineCode parentName=\"p\">{`flask-caching`}</inlineCode>{`, `}<inlineCode parentName=\"p\">{`flask-migrate`}</inlineCode>{`,\nand `}<inlineCode parentName=\"p\">{`flask-appbuilder`}</inlineCode>{`. Flask App Builder, the web framework used by Superset, offers many\nconfiguration settings. Please consult the\n`}<a parentName=\"p\" {...{\n \"href\": \"https://flask-appbuilder.readthedocs.org/en/latest/config.html\"\n }}>{`Flask App Builder Documentation`}</a>{`\nfor more information on how to configure it.`}</p>\n <p>{`Make sure to change:`}</p>\n <ul>\n <li parentName=\"ul\"><inlineCode parentName=\"li\">{`SQLALCHEMY_DATABASE_URI`}</inlineCode>{`: by default it is stored at ~/.superset/superset.db`}</li>\n <li parentName=\"ul\"><inlineCode parentName=\"li\">{`SECRET_KEY`}</inlineCode>{`: to a long random string`}</li>\n </ul>\n <p>{`If you need to exempt endpoints from CSRF (e.g. if you are running a custom auth postback endpoint),\nyou can add the endpoints to `}<inlineCode parentName=\"p\">{`WTF_CSRF_EXEMPT_LIST`}</inlineCode>{`:`}</p>\n <pre><code parentName=\"pre\" {...{}}>{`WTF_CSRF_EXEMPT_LIST = [‘’]\n`}</code></pre>\n <h3 {...{\n \"id\": \"running-on-a-wsgi-http-server\"\n }}>{`Running on a WSGI HTTP Server`}</h3>\n <p>{`While you can run Superset on NGINX or Apache, we recommend using Gunicorn in async mode. This\nenables impressive concurrency even and is fairly easy to install and configure. Please refer to the\ndocumentation of your preferred technology to set up this Flask WSGI application in a way that works\nwell in your environment. Here’s an async setup known to work well in production:`}</p>\n <pre><code parentName=\"pre\" {...{}}>{` -w 10 \\\\\n -k gevent \\\\\n --timeout 120 \\\\\n -b 0.0.0.0:6666 \\\\\n --limit-request-line 0 \\\\\n --limit-request-field_size 0 \\\\\n --statsd-host localhost:8125 \\\\\n \"superset.app:create_app()\"\n`}</code></pre>\n <p>{`Refer to the `}<a parentName=\"p\" {...{\n \"href\": \"https://docs.gunicorn.org/en/stable/design.html\"\n }}>{`Gunicorn documentation`}</a>{` for more\ninformation. `}<em parentName=\"p\">{`Note that the development web server (`}<inlineCode parentName=\"em\">{`superset run`}</inlineCode>{` or `}<inlineCode parentName=\"em\">{`flask run`}</inlineCode>{`) is not intended\nfor production use.`}</em></p>\n <p>{`If you're not using Gunicorn, you may want to disable the use of `}<inlineCode parentName=\"p\">{`flask-compress`}</inlineCode>{` by setting\n`}<inlineCode parentName=\"p\">{`COMPRESS_REGISTER = False`}</inlineCode>{` in your `}<inlineCode parentName=\"p\">{`superset_config.py`}</inlineCode>{`.`}</p>\n <h3 {...{\n \"id\": \"configuration-behind-a-load-balancer\"\n }}>{`Configuration Behind a Load Balancer`}</h3>\n <p>{`If you are running superset behind a load balancer or reverse proxy (e.g. NGINX or ELB on AWS), you\nmay need to utilize a healthcheck endpoint so that your load balancer knows if your superset\ninstance is running. This is provided at `}<inlineCode parentName=\"p\">{`/health`}</inlineCode>{` which will return a 200 response containing “OK”\nif the the webserver is running.`}</p>\n <p>{`If the load balancer is inserting `}<inlineCode parentName=\"p\">{`X-Forwarded-For/X-Forwarded-Proto`}</inlineCode>{` headers, you should set\n`}<inlineCode parentName=\"p\">{`ENABLE_PROXY_FIX = True`}</inlineCode>{` in the superset config file (`}<inlineCode parentName=\"p\">{`superset_config.py`}</inlineCode>{`) to extract and use the\nheaders.`}</p>\n <p>{`In case the reverse proxy is used for providing SSL encryption, an explicit definition of the\n`}<inlineCode parentName=\"p\">{`X-Forwarded-Proto`}</inlineCode>{` may be required. For the Apache webserver this can be set as follows:`}</p>\n <pre><code parentName=\"pre\" {...{}}>{`RequestHeader set X-Forwarded-Proto \"https\"\n`}</code></pre>\n <h3 {...{\n \"id\": \"custom-oauth2-configuration\"\n }}>{`Custom OAuth2 Configuration`}</h3>\n <p>{`Beyond FAB supported providers (Github, Twitter, LinkedIn, Google, Azure, etc), its easy to connect\nSuperset with other OAuth2 Authorization Server implementations that support “code” authorization.`}</p>\n <p>{`Make sure the pip package `}<a parentName=\"p\" {...{\n \"href\": \"https://authlib.org/\"\n }}><inlineCode parentName=\"a\">{`Authlib`}</inlineCode></a>{` is installed on the webserver.`}</p>\n <p>{`First, configure authorization in Superset `}<inlineCode parentName=\"p\">{`superset_config.py`}</inlineCode>{`.`}</p>\n <pre><code parentName=\"pre\" {...{\n \"className\": \"language-python\"\n }}>{`AUTH_TYPE = AUTH_OAUTH\nOAUTH_PROVIDERS = [\n { 'name':'egaSSO',\n 'token_key':'access_token', # Name of the token in the response of access_token_url\n 'icon':'fa-address-card', # Icon for the provider\n 'remote_app': {\n 'client_id':'myClientId', # Client Id (Identify Superset application)\n 'client_secret':'MySecret', # Secret for this Client Id (Identify Superset application)\n 'client_kwargs':{\n 'scope': 'read' # Scope for the Authorization\n },\n 'access_token_method':'POST', # HTTP Method to call access_token_url\n 'access_token_params':{ # Additional parameters for calls to access_token_url\n 'client_id':'myClientId'\n },\n 'access_token_headers':{ # Additional headers for calls to access_token_url\n 'Authorization': 'Basic Base64EncodedClientIdAndSecret'\n },\n 'api_base_url':'https://myAuthorizationServer/oauth2AuthorizationServer/',\n 'access_token_url':'https://myAuthorizationServer/oauth2AuthorizationServer/token',\n 'authorize_url':'https://myAuthorizationServer/oauth2AuthorizationServer/authorize'\n }\n }\n]\n\n# Will allow user self registration, allowing to create Flask users from Authorized User\nAUTH_USER_REGISTRATION = True\n\n# The default user self registration role\nAUTH_USER_REGISTRATION_ROLE = \"Public\"\n`}</code></pre>\n <p>{`Then, create a `}<inlineCode parentName=\"p\">{`CustomSsoSecurityManager`}</inlineCode>{` that extends `}<inlineCode parentName=\"p\">{`SupersetSecurityManager`}</inlineCode>{` and overrides\n`}<inlineCode parentName=\"p\">{`oauth_user_info`}</inlineCode>{`:`}</p>\n <pre><code parentName=\"pre\" {...{\n \"className\": \"language-python\"\n }}>{`from superset.security import SupersetSecurityManager\n\nclass CustomSsoSecurityManager(SupersetSecurityManager):\n\n def oauth_user_info(self, provider, response=None):\n logging.debug(\"Oauth2 provider: {0}.\".format(provider))\n if provider == 'egaSSO':\n # As example, this line request a GET to base_url + '/' + userDetails with Bearer Authentication,\n # and expects that authorization server checks the token, and response with user details\n me = self.appbuilder.sm.oauth_remotes[provider].get('userDetails').data\n logging.debug(\"user_data: {0}\".format(me))\n return { 'name' : me['name'], 'email' : me['email'], 'id' : me['user_name'], 'username' : me['user_name'], 'first_name':'', 'last_name':''}\n ...\n`}</code></pre>\n <p>{`This file must be located at the same directory than `}<inlineCode parentName=\"p\">{`superset_config.py`}</inlineCode>{` with the name\n`}<inlineCode parentName=\"p\">{`custom_sso_security_manager.py`}</inlineCode>{`. Finally, add the following 2 lines to `}<inlineCode parentName=\"p\">{`superset_config.py`}</inlineCode>{`:`}</p>\n <pre><code parentName=\"pre\" {...{}}>{`from custom_sso_security_manager import CustomSsoSecurityManager\nCUSTOM_SECURITY_MANAGER = CustomSsoSecurityManager\n`}</code></pre>\n <p><strong parentName=\"p\">{`Notes`}</strong></p>\n <ul>\n <li parentName=\"ul\">\n <p parentName=\"li\">{`The redirect URL will be `}<inlineCode parentName=\"p\">{`https://<superset-webserver>/oauth-authorized/<provider-name>`}</inlineCode>{`\nWhen configuring an OAuth2 authorization provider if needed. For instance, the redirect URL will\nbe `}<inlineCode parentName=\"p\">{`https://<superset-webserver>/oauth-authorized/egaSSO`}</inlineCode>{` for the above configuration.`}</p>\n </li>\n <li parentName=\"ul\">\n <p parentName=\"li\">{`If an OAuth2 authorization server supports OpenID Connect 1.0, you could configure its configuration\ndocument URL only without providing `}<inlineCode parentName=\"p\">{`api_base_url`}</inlineCode>{`, `}<inlineCode parentName=\"p\">{`access_token_url`}</inlineCode>{`, `}<inlineCode parentName=\"p\">{`authorize_url`}</inlineCode>{` and other\nrequired options like user info endpoint, jwks uri etc. For instance:`}</p>\n <pre parentName=\"li\"><code parentName=\"pre\" {...{\n \"className\": \"language-python\"\n }}>{`OAUTH_PROVIDERS = [\n { 'name':'egaSSO',\n 'token_key':'access_token', # Name of the token in the response of access_token_url\n 'icon':'fa-address-card', # Icon for the provider\n 'remote_app': {\n 'client_id':'myClientId', # Client Id (Identify Superset application)\n 'client_secret':'MySecret', # Secret for this Client Id (Identify Superset application)\n 'server_metadata_url': 'https://myAuthorizationServer/.well-known/openid-configuration'\n }\n }\n]\n`}</code></pre>\n </li>\n </ul>\n <h3 {...{\n \"id\": \"feature-flags\"\n }}>{`Feature Flags`}</h3>\n <p>{`To support a diverse set of users, Superset has some features that are not enabled by default. For\nexample, some users have stronger security restrictions, while some others may not. So Superset\nallow users to enable or disable some features by config. For feature owners, you can add optional\nfunctionalities in Superset, but will be only affected by a subset of users.`}</p>\n <p>{`You can enable or disable features with flag from `}<inlineCode parentName=\"p\">{`superset_config.py`}</inlineCode>{`:`}</p>\n <pre><code parentName=\"pre\" {...{\n \"className\": \"language-python\"\n }}>{`FEATURE_FLAGS = {\n 'CLIENT_CACHE': False,\n 'ENABLE_EXPLORE_JSON_CSRF_PROTECTION': False,\n 'PRESTO_EXPAND_DATA': False,\n}\n`}</code></pre>\n <p>{`A current list of feature flags can be found in `}<inlineCode parentName=\"p\">{`RESOURCES/FEATURE_FLAGS.md`}</inlineCode></p>\n <h3 {...{\n \"id\": \"sip-15\"\n }}>{`SIP 15`}</h3>\n <p><a parentName=\"p\" {...{\n \"href\": \"https://github.com/apache/superset/issues/6360\"\n }}>{`Superset Improvement Proposal 15`}</a>{` aims to\nensure that time intervals are handled in a consistent and transparent manner for both the Druid and\nSQLAlchemy connectors.`}</p>\n <p>{`Prior to SIP-15 SQLAlchemy used inclusive endpoints however these may behave like exclusive for\nstring columns (due to lexicographical ordering) if no formatting was defined and the column\nformatting did not conform to an ISO 8601 date-time (refer to the SIP for details).`}</p>\n <p>{`To remedy this rather than having to define the date/time format for every non-IS0 8601 date-time\ncolumn, once can define a default column mapping on a per database level via the `}<inlineCode parentName=\"p\">{`extra`}</inlineCode>{` parameter:`}</p>\n <pre><code parentName=\"pre\" {...{}}>{`{\n \"python_date_format_by_column_name\": {\n \"ds\": \"%Y-%m-%d\"\n }\n}\n`}</code></pre>\n <p><strong parentName=\"p\">{`New Deployments`}</strong></p>\n <p>{`All new deployments should enable SIP-15 by setting this value in `}<inlineCode parentName=\"p\">{`superset_config.py`}</inlineCode>{`:`}</p>\n <pre><code parentName=\"pre\" {...{}}>{`SIP_15_ENABLED = True\n\n`}</code></pre>\n <p><strong parentName=\"p\">{`Existing Deployments`}</strong></p>\n <p>{`Given that it is not apparent whether the chart creator was aware of the time range inconsistencies\n(and adjusted the endpoints accordingly) changing the behavior of all charts is overly aggressive.\nInstead SIP-15 proivides a soft transistion allowing producers (chart owners) to see the impact of\nthe proposed change and adjust their charts accordingly.`}</p>\n <p>{`Prior to enabling SIP-15, existing deployments should communicate to their users the impact of the\nchange and define a grace period end date (exclusive of course) after which all charts will conform\nto the [start, end) interval.`}</p>\n <pre><code parentName=\"pre\" {...{\n \"className\": \"language-python\"\n }}>{`from dateime import date\n\nSIP_15_ENABLED = True\nSIP_15_GRACE_PERIOD_END = date(<YYYY>, <MM>, <DD>)\n`}</code></pre>\n <p>{`To aid with transparency the current endpoint behavior is explicitly called out in the chart time\nrange (post SIP-15 this will be [start, end) for all connectors and databases). One can override the\ndefaults on a per database level via the `}<inlineCode parentName=\"p\">{`extra`}</inlineCode>{` parameter.`}</p>\n <pre><code parentName=\"pre\" {...{\n \"className\": \"language-python\"\n }}>{`{\n \"time_range_endpoints\": [\"inclusive\", \"inclusive\"]\n}\n`}</code></pre>\n <p>{`Note in a future release the interim SIP-15 logic will be removed (including the\n`}<inlineCode parentName=\"p\">{`time_grain_endpoints`}</inlineCode>{` form-data field) via a code change and Alembic migration.`}</p>\n\n </MDXLayout>;\n}\n;\nMDXContent.isMDXComponent = true;\n "],"sourceRoot":""}