You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@superset.apache.org by GitBox <gi...@apache.org> on 2020/09/04 01:03:28 UTC

[GitHub] [incubator-superset] ktmud commented on a change in pull request #10784: docs(new docs site): removes old sphinx doc site with gatsby

ktmud commented on a change in pull request #10784:
URL: https://github.com/apache/incubator-superset/pull/10784#discussion_r483329332



##########
File path: docs/src/pages/docs/installation/upgrading_superset.mdx
##########
@@ -0,0 +1,44 @@
+---
+name: Upgrading Superset
+menu: Installation and Configuration
+route: /docs/installation/upgrading-superset
+index: 6
+version: 1
+---
+
+## Upgrading Superset
+
+### Docker Compose
+
+First make sure to wind down the running containers in Docker Compose:
+
+```
+docker-compose down
+```
+
+Then, update the folder that mirrors the `incubator-superset` repo through git:
+
+```
+cd incubator_superset/
+git pull origin master
+```
+
+Then, restart the containers and any changed Docker images will be automatically pulled down:
+
+```
+docker-compose up
+```
+
+### Updating Superset Manually
+
+To upgrade superset in a native installation, run the following commands:
+
+```python

Review comment:
       The language should probably be `bash` or `shell`

##########
File path: docs/prettier.config.js
##########
@@ -0,0 +1,3 @@
+{ 
+	"endOfLine":"lf", "semi":false,"singleQuote":false,"tabWidth": 2,"trailingComma":"es5"
+}

Review comment:
       Nit: might want to format this file a bit. I'm also not sure whether the docs folder should have its own prettier config.  Would replacing this with `module.exports = require('../superset-frontend/prettier.config')` work? (Might need to rename `superset-frontend/.prettierrc` to `superset-frontend/prettier.config.js`).

##########
File path: docs/src/pages/docs/installation/configuring.mdx
##########
@@ -0,0 +1,282 @@
+---
+name: Configuring Superset
+menu: Installation and Configuration
+route: /docs/installation/configuring-superset
+index: 3
+version: 1
+---
+
+## Configuring Superset
+
+### Configuration
+
+To configure your application, you need to create a file `superset_config.py` and add it to your
+`PYTHONPATH`. Here are some of the parameters you can set in that file:
+
+```

Review comment:
       ```suggestion
   ```python
   ```

##########
File path: docs/src/pages/docs/installation/configuring.mdx
##########
@@ -0,0 +1,282 @@
+---
+name: Configuring Superset
+menu: Installation and Configuration
+route: /docs/installation/configuring-superset
+index: 3
+version: 1
+---
+
+## Configuring Superset
+
+### Configuration
+
+To configure your application, you need to create a file `superset_config.py` and add it to your
+`PYTHONPATH`. Here are some of the parameters you can set in that file:
+
+```
+# Superset specific config
+ROW_LIMIT = 5000
+
+SUPERSET_WEBSERVER_PORT = 8088
+
+# Flask App Builder configuration
+# Your App secret key
+SECRET_KEY = '\2\1thisismyscretkey\1\2\e\y\y\h'
+
+# The SQLAlchemy connection string to your database backend
+# This connection defines the path to the database that stores your
+# superset metadata (slices, connections, tables, dashboards, ...).
+# Note that the connection information to connect to the datasources
+# you want to explore are managed directly in the web UI
+SQLALCHEMY_DATABASE_URI = 'sqlite:////path/to/superset.db'
+
+# Flask-WTF flag for CSRF
+WTF_CSRF_ENABLED = True
+# Add endpoints that need to be exempt from CSRF protection
+WTF_CSRF_EXEMPT_LIST = []
+# A CSRF token that expires in 1 year
+WTF_CSRF_TIME_LIMIT = 60 * 60 * 24 * 365
+
+# Set this API key to enable Mapbox visualizations
+MAPBOX_API_KEY = ''
+```
+
+All the parameters and default values defined in
+[https://github.com/apache/incubator-superset/blob/master/superset/config.py](https://github.com/apache/incubator-superset/blob/master/superset/config.py)
+can be altered in your local `superset_config.py`. Administrators will want to read through the file
+to understand what can be configured locally as well as the default values in place.
+
+Since `superset_config.py` acts as a Flask configuration module, it can be used to alter the
+settings Flask itself, as well as Flask extensions like `flask-wtf`, `flask-cache`, `flask-migrate`,
+and `flask-appbuilder`. Flask App Builder, the web framework used by Superset, offers many
+configuration settings. Please consult the
+[Flask App Builder Documentation](https://flask-appbuilder.readthedocs.org/en/latest/config.html)
+for more information on how to configure it.
+
+Make sure to change:
+
+- `SQLALCHEMY_DATABASE_URI`: by default it is stored at ~/.superset/superset.db
+- `SECRET_KEY`: to a long random string
+
+If you need to exempt endpoints from CSRF (e.g. if you are running a custom auth postback endpoint),
+you can add the endpoints to `WTF_CSRF_EXEMPT_LIST`:
+
+```
+WTF_CSRF_EXEMPT_LIST = [‘’]
+```
+
+### Flask AppBuilder Permissions
+
+By default, every time the Flask-AppBuilder (FAB) app is initialized the permissions and views are
+added automatically to the backend and associated with the ‘Admin’ role. The issue, however, is when
+you are running multiple concurrent workers this creates a lot of contention and race conditions
+when defining permissions and views.
+
+To alleviate this issue, the automatic updating of permissions can be disabled by setting
+`FAB_UPDATE_PERMS = False` (defaults to True).
+
+In a production environment initialization could take on the following form:
+
+```
+superset init gunicorn -w 10 … superset:app
+```
+
+### Running on a WSGI HTTP Server
+
+While you can run Superset on NGINX or Apache, we recommend using Gunicorn in async mode. This
+enables impressive concurrency even and is fairly easy to install and configure. Please refer to the
+documentation of your preferred technology to set up this Flask WSGI application in a way that works
+well in your environment. Here’s an async setup known to work well in production:
+
+```
+      -w 10 \
+      -k gevent \
+      --timeout 120 \
+      -b  0.0.0.0:6666 \
+      --limit-request-line 0 \
+      --limit-request-field_size 0 \
+      --statsd-host localhost:8125 \
+      "superset.app:create_app()"
+```
+
+Refer to the [Gunicorn documentation](https://docs.gunicorn.org/en/stable/design.html) for more
+information. _Note that the development web server (`superset run` or `flask run`) is not intended
+for production use._
+
+If you're not using Gunicorn, you may want to disable the use of `flask-compress` by setting
+`COMPRESS_REGISTER = False` in your `superset_config.py`.
+
+### Configuration Behind a Load Balancer
+
+If you are running superset behind a load balancer or reverse proxy (e.g. NGINX or ELB on AWS), you
+may need to utilize a healthcheck endpoint so that your load balancer knows if your superset
+instance is running. This is provided at `/health` which will return a 200 response containing “OK”
+if the the webserver is running.
+
+If the load balancer is inserting `X-Forwarded-For/X-Forwarded-Proto` headers, you should set
+`ENABLE_PROXY_FIX = True` in the superset config file (`superset_config.py`) to extract and use the
+headers.
+
+In case the reverse proxy is used for providing SSL encryption, an explicit definition of the
+`X-Forwarded-Proto` may be required. For the Apache webserver this can be set as follows:
+
+```
+RequestHeader set X-Forwarded-Proto "https"
+```
+
+### Custom OAuth2 Configuration
+
+Beyond FAB supported providers (Github, Twitter, LinkedIn, Google, Azure, etc), its easy to connect
+Superset with other OAuth2 Authorization Server implementations that support “code” authorization.
+
+First, configure authorization in Superset `superset_config.py`.
+
+```python
+AUTH_TYPE = AUTH_OAUTH
+OAUTH_PROVIDERS = [
+    {   'name':'egaSSO',
+        'token_key':'access_token', # Name of the token in the response of access_token_url
+        'icon':'fa-address-card',   # Icon for the provider
+        'remote_app': {
+            'consumer_key':'myClientId',  # Client Id (Identify Superset application)
+            'consumer_secret':'MySecret', # Secret for this Client Id (Identify Superset application)
+            'request_token_params':{
+                'scope': 'read'               # Scope for the Authorization
+            },
+            'access_token_method':'POST',    # HTTP Method to call access_token_url
+            'access_token_params':{        # Additional parameters for calls to access_token_url
+                'client_id':'myClientId'
+            },
+            'access_token_headers':{    # Additional headers for calls to access_token_url
+                'Authorization': 'Basic Base64EncodedClientIdAndSecret'
+            },
+            'base_url':'https://myAuthorizationServer/oauth2AuthorizationServer/',
+            'access_token_url':'https://myAuthorizationServer/oauth2AuthorizationServer/token',
+            'authorize_url':'https://myAuthorizationServer/oauth2AuthorizationServer/authorize'
+        }
+    }
+]
+
+# Will allow user self registration, allowing to create Flask users from Authorized User
+AUTH_USER_REGISTRATION = True
+
+# The default user self registration role
+AUTH_USER_REGISTRATION_ROLE = "Public"
+```
+
+Then, create a `CustomSsoSecurityManager` that extends `SupersetSecurityManager` and overrides
+`oauth_user_info`:
+
+```python
+from superset.security import SupersetSecurityManager
+
+class CustomSsoSecurityManager(SupersetSecurityManager):
+
+    def oauth_user_info(self, provider, response=None):
+        logging.debug("Oauth2 provider: {0}.".format(provider))
+        if provider == 'egaSSO':
+            # As example, this line request a GET to base_url + '/' + userDetails with Bearer  Authentication,
+    # and expects that authorization server checks the token, and response with user details
+            me = self.appbuilder.sm.oauth_remotes[provider].get('userDetails').data
+            logging.debug("user_data: {0}".format(me))
+            return { 'name' : me['name'], 'email' : me['email'], 'id' : me['user_name'], 'username' : me['user_name'], 'first_name':'', 'last_name':''}
+    ...
+```
+
+This file must be located at the same directory than `superset_config.py` with the name
+`custom_sso_security_manager.py`. Finally, add the following 2 lines to `superset_config.py`:
+
+```

Review comment:
       ```suggestion
   ```python
   ```

##########
File path: docs/src/pages/docs/installation/email_reports.mdx
##########
@@ -0,0 +1,174 @@
+---
+name: Scheduling and Emailing Reports
+menu: Installation and Configuration
+route: /docs/installation/email-reports
+index: 10
+version: 1
+---
+
+## Scheduling and Emailing Reports
+
+### Email Reports
+
+Email reports allow users to schedule email reports for:
+
+- chart and dashboard visualization (attachment or inline)
+- chart data (CSV attachment on inline table)
+
+Enable email reports in your `superset_config.py` file:
+
+```
+ENABLE_SCHEDULED_EMAIL_REPORTS = True
+```
+
+Now you will find two new items in the navigation bar that allow you to schedule email reports:
+
+- **Manage > Dashboard Emails**
+- **Manage > Chart Email Schedules**
+
+Schedules are defined in [crontab format](https://crontab.guru/) and each schedule can have a list
+of recipients (all of them can receive a single mail, or separate mails). For audit purposes, all
+outgoing mails can have a mandatory BCC.
+
+In order get picked up you need to configure a celery worker and a celery beat (see section above
+“Celery Tasks”). Your celery configuration also needs an entry `email_reports.schedule_hourly` for
+`CELERYBEAT_SCHEDULE`.
+
+To send emails you need to configure SMTP settings in your `superset_config.py` configuration file.
+
+```
+EMAIL_NOTIFICATIONS = True
+
+SMTP_HOST = "email-smtp.eu-west-1.amazonaws.com"
+SMTP_STARTTLS = True
+SMTP_SSL = False
+SMTP_USER = "smtp_username"
+SMTP_PORT = 25
+SMTP_PASSWORD = os.environ.get("SMTP_PASSWORD")
+SMTP_MAIL_FROM = "insights@komoot.com"
+```
+
+To render dashboards you need to install a local browser on your Superset instance:
+
+- [geckodriver](https://github.com/mozilla/geckodriver) for Firefox
+- [chromedriver](http://chromedriver.chromium.org/) for Chrome
+
+You'll need to adjust the `EMAIL_REPORTS_WEBDRIVER` accordingly in your configuration. 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.
+
+```
+EMAIL_REPORTS_USER = 'username_with_permission_to_access_dashboards'
+```
+
+**Important notes**
+
+- Be mindful of the concurrency setting for celery (using `-c 4`). Selenium/webdriver instances can
+  consume a lot of CPU / memory on your servers.
+- In some cases, if you notice a lot of leaked geckodriver processes, try running your celery
+  processes with `celery worker --pool=prefork --max-tasks-per-child=128 ...`
+- It is recommended to run separate workers for the `sql_lab` and `email_reports` tasks. This can be
+  done using the `queue` field in `CELERY_ANNOTATIONS`.
+- Adjust `WEBDRIVER_BASEURL` in your configuration file if celery workers can’t access Superset via
+  its default value of `http://0.0.0.0:8080/`.
+
+### Schedule Reports
+
+You can optionally allow your users to schedule queries directly in SQL Lab. This is done by addding
+extra metadata to saved queries, which are then picked up by an external scheduled (like
+[Apache Airflow](https://airflow.apache.org/)).
+
+To allow scheduled queries, add the following to your configuration file:
+
+```

Review comment:
       ```suggestion
   ```python
   ```

##########
File path: docs/src/pages/docs/installation/sql_templating.mdx
##########
@@ -0,0 +1,89 @@
+---
+name: SQL Templating
+menu: Installation and Configuration
+route: /docs/installation/sql-templating
+index: 10
+version: 1
+---
+
+## SQL Templating
+
+### Jinja Templates
+
+SQL Lab supports [Jinja templating](https://jinja.palletsprojects.com/en/2.11.x/) in queries. You'll
+need to to overload the default Jinja context in your environment by defining the
+JINJA_CONTEXT_ADDONS in your superset configuration (`superset_config.py`). Objects referenced in
+this dictionary are made available for users to use in their SQL code.
+
+```
+JINJA_CONTEXT_ADDONS = {
+    'my_crazy_macro': lambda x: x*2,
+}
+```
+
+Besides default Jinja templating, SQL lab also supports self-defined template processor by setting
+the `CUSTOM_TEMPLATE_PROCESSORS` in your superset configuration. The values in this dictionary
+overwrite the default Jinja template processors of the specified database engine. The example below
+configures a custom presto template processor which implements its own logic of processing macro
+template with regex parsing. It uses the `$` style macro instead of `{{ }}` style in Jinja
+templating.
+
+By configuring it with `CUSTOM_TEMPLATE_PROCESSORS`, a SQL template on a presto database is
+processed by the custom one rather than the default one.
+
+```python
+def DATE(
+    ts: datetime, day_offset: SupportsInt = 0, hour_offset: SupportsInt = 0
+) -> str:
+    """Current day as a string."""
+    day_offset, hour_offset = int(day_offset), int(hour_offset)
+    offset_day = (ts + timedelta(days=day_offset, hours=hour_offset)).date()
+    return str(offset_day)
+
+class CustomPrestoTemplateProcessor(PrestoTemplateProcessor):
+    """A custom presto template processor."""
+
+    engine = "presto"
+
+    def process_template(self, sql: str, **kwargs) -> str:
+        """Processes a sql template with $ style macro using regex."""
+        # Add custom macros functions.
+        macros = {
+            "DATE": partial(DATE, datetime.utcnow())
+        }  # type: Dict[str, Any]
+        # Update with macros defined in context and kwargs.
+        macros.update(self.context)
+        macros.update(kwargs)
+
+        def replacer(match):
+            """Expand $ style macros with corresponding function calls."""
+            macro_name, args_str = match.groups()
+            args = [a.strip() for a in args_str.split(",")]
+            if args == [""]:
+                args = []
+            f = macros[macro_name[1:]]
+            return f(*args)
+
+        macro_names = ["$" + name for name in macros.keys()]
+        pattern = r"(%s)\s*\(([^()]*)\)" % "|".join(map(re.escape, macro_names))
+        return re.sub(pattern, replacer, sql)
+
+CUSTOM_TEMPLATE_PROCESSORS = {
+    CustomPrestoTemplateProcessor.engine: CustomPrestoTemplateProcessor
+}
+```
+
+SQL Lab also includes a live query validation feature with pluggable backends. You can configure
+which validation implementation is used with which database engine by adding a block like the
+following to your configuration file:
+
+```

Review comment:
       Nit 
   
   ```suggestion
   ```python
   ```

##########
File path: docs/gatsby-config.js
##########
@@ -0,0 +1,56 @@
+module.exports = {
+  siteMetadata: {
+    title: `Superset`,
+    description: `Kick off your next, great Gatsby project with this default starter. This barebones starter ships with the main Gatsby configuration files you might need.`,
+    author: `@gatsbyjs`,

Review comment:
       Can update `description` and `author` or remove them if not needed.

##########
File path: docs/src/pages/docs/installation/email_reports.mdx
##########
@@ -0,0 +1,174 @@
+---
+name: Scheduling and Emailing Reports
+menu: Installation and Configuration
+route: /docs/installation/email-reports
+index: 10
+version: 1
+---
+
+## Scheduling and Emailing Reports
+
+### Email Reports
+
+Email reports allow users to schedule email reports for:
+
+- chart and dashboard visualization (attachment or inline)
+- chart data (CSV attachment on inline table)
+
+Enable email reports in your `superset_config.py` file:
+
+```
+ENABLE_SCHEDULED_EMAIL_REPORTS = True
+```
+
+Now you will find two new items in the navigation bar that allow you to schedule email reports:
+
+- **Manage > Dashboard Emails**
+- **Manage > Chart Email Schedules**
+
+Schedules are defined in [crontab format](https://crontab.guru/) and each schedule can have a list
+of recipients (all of them can receive a single mail, or separate mails). For audit purposes, all
+outgoing mails can have a mandatory BCC.
+
+In order get picked up you need to configure a celery worker and a celery beat (see section above
+“Celery Tasks”). Your celery configuration also needs an entry `email_reports.schedule_hourly` for
+`CELERYBEAT_SCHEDULE`.
+
+To send emails you need to configure SMTP settings in your `superset_config.py` configuration file.
+
+```

Review comment:
       ```suggestion
   ```python
   ```

##########
File path: docs/src/pages/docs/installation/configuring.mdx
##########
@@ -0,0 +1,282 @@
+---
+name: Configuring Superset
+menu: Installation and Configuration
+route: /docs/installation/configuring-superset
+index: 3
+version: 1
+---
+
+## Configuring Superset
+
+### Configuration
+
+To configure your application, you need to create a file `superset_config.py` and add it to your
+`PYTHONPATH`. Here are some of the parameters you can set in that file:
+
+```
+# Superset specific config
+ROW_LIMIT = 5000
+
+SUPERSET_WEBSERVER_PORT = 8088
+
+# Flask App Builder configuration
+# Your App secret key
+SECRET_KEY = '\2\1thisismyscretkey\1\2\e\y\y\h'
+
+# The SQLAlchemy connection string to your database backend
+# This connection defines the path to the database that stores your
+# superset metadata (slices, connections, tables, dashboards, ...).
+# Note that the connection information to connect to the datasources
+# you want to explore are managed directly in the web UI
+SQLALCHEMY_DATABASE_URI = 'sqlite:////path/to/superset.db'
+
+# Flask-WTF flag for CSRF
+WTF_CSRF_ENABLED = True
+# Add endpoints that need to be exempt from CSRF protection
+WTF_CSRF_EXEMPT_LIST = []
+# A CSRF token that expires in 1 year
+WTF_CSRF_TIME_LIMIT = 60 * 60 * 24 * 365
+
+# Set this API key to enable Mapbox visualizations
+MAPBOX_API_KEY = ''
+```
+
+All the parameters and default values defined in
+[https://github.com/apache/incubator-superset/blob/master/superset/config.py](https://github.com/apache/incubator-superset/blob/master/superset/config.py)
+can be altered in your local `superset_config.py`. Administrators will want to read through the file
+to understand what can be configured locally as well as the default values in place.
+
+Since `superset_config.py` acts as a Flask configuration module, it can be used to alter the
+settings Flask itself, as well as Flask extensions like `flask-wtf`, `flask-cache`, `flask-migrate`,
+and `flask-appbuilder`. Flask App Builder, the web framework used by Superset, offers many
+configuration settings. Please consult the
+[Flask App Builder Documentation](https://flask-appbuilder.readthedocs.org/en/latest/config.html)
+for more information on how to configure it.
+
+Make sure to change:
+
+- `SQLALCHEMY_DATABASE_URI`: by default it is stored at ~/.superset/superset.db
+- `SECRET_KEY`: to a long random string
+
+If you need to exempt endpoints from CSRF (e.g. if you are running a custom auth postback endpoint),
+you can add the endpoints to `WTF_CSRF_EXEMPT_LIST`:
+
+```
+WTF_CSRF_EXEMPT_LIST = [‘’]
+```
+
+### Flask AppBuilder Permissions
+
+By default, every time the Flask-AppBuilder (FAB) app is initialized the permissions and views are
+added automatically to the backend and associated with the ‘Admin’ role. The issue, however, is when
+you are running multiple concurrent workers this creates a lot of contention and race conditions
+when defining permissions and views.
+
+To alleviate this issue, the automatic updating of permissions can be disabled by setting
+`FAB_UPDATE_PERMS = False` (defaults to True).
+
+In a production environment initialization could take on the following form:
+
+```
+superset init gunicorn -w 10 … superset:app
+```
+
+### Running on a WSGI HTTP Server
+
+While you can run Superset on NGINX or Apache, we recommend using Gunicorn in async mode. This
+enables impressive concurrency even and is fairly easy to install and configure. Please refer to the
+documentation of your preferred technology to set up this Flask WSGI application in a way that works
+well in your environment. Here’s an async setup known to work well in production:
+
+```
+      -w 10 \
+      -k gevent \
+      --timeout 120 \
+      -b  0.0.0.0:6666 \
+      --limit-request-line 0 \
+      --limit-request-field_size 0 \
+      --statsd-host localhost:8125 \
+      "superset.app:create_app()"
+```
+
+Refer to the [Gunicorn documentation](https://docs.gunicorn.org/en/stable/design.html) for more
+information. _Note that the development web server (`superset run` or `flask run`) is not intended
+for production use._
+
+If you're not using Gunicorn, you may want to disable the use of `flask-compress` by setting
+`COMPRESS_REGISTER = False` in your `superset_config.py`.
+
+### Configuration Behind a Load Balancer
+
+If you are running superset behind a load balancer or reverse proxy (e.g. NGINX or ELB on AWS), you
+may need to utilize a healthcheck endpoint so that your load balancer knows if your superset
+instance is running. This is provided at `/health` which will return a 200 response containing “OK”
+if the the webserver is running.
+
+If the load balancer is inserting `X-Forwarded-For/X-Forwarded-Proto` headers, you should set
+`ENABLE_PROXY_FIX = True` in the superset config file (`superset_config.py`) to extract and use the
+headers.
+
+In case the reverse proxy is used for providing SSL encryption, an explicit definition of the
+`X-Forwarded-Proto` may be required. For the Apache webserver this can be set as follows:
+
+```
+RequestHeader set X-Forwarded-Proto "https"
+```
+
+### Custom OAuth2 Configuration
+
+Beyond FAB supported providers (Github, Twitter, LinkedIn, Google, Azure, etc), its easy to connect
+Superset with other OAuth2 Authorization Server implementations that support “code” authorization.
+
+First, configure authorization in Superset `superset_config.py`.
+
+```python
+AUTH_TYPE = AUTH_OAUTH
+OAUTH_PROVIDERS = [
+    {   'name':'egaSSO',
+        'token_key':'access_token', # Name of the token in the response of access_token_url
+        'icon':'fa-address-card',   # Icon for the provider
+        'remote_app': {
+            'consumer_key':'myClientId',  # Client Id (Identify Superset application)
+            'consumer_secret':'MySecret', # Secret for this Client Id (Identify Superset application)
+            'request_token_params':{
+                'scope': 'read'               # Scope for the Authorization
+            },
+            'access_token_method':'POST',    # HTTP Method to call access_token_url
+            'access_token_params':{        # Additional parameters for calls to access_token_url
+                'client_id':'myClientId'
+            },
+            'access_token_headers':{    # Additional headers for calls to access_token_url
+                'Authorization': 'Basic Base64EncodedClientIdAndSecret'
+            },
+            'base_url':'https://myAuthorizationServer/oauth2AuthorizationServer/',
+            'access_token_url':'https://myAuthorizationServer/oauth2AuthorizationServer/token',
+            'authorize_url':'https://myAuthorizationServer/oauth2AuthorizationServer/authorize'
+        }
+    }
+]
+
+# Will allow user self registration, allowing to create Flask users from Authorized User
+AUTH_USER_REGISTRATION = True
+
+# The default user self registration role
+AUTH_USER_REGISTRATION_ROLE = "Public"
+```
+
+Then, create a `CustomSsoSecurityManager` that extends `SupersetSecurityManager` and overrides
+`oauth_user_info`:
+
+```python
+from superset.security import SupersetSecurityManager
+
+class CustomSsoSecurityManager(SupersetSecurityManager):
+
+    def oauth_user_info(self, provider, response=None):
+        logging.debug("Oauth2 provider: {0}.".format(provider))
+        if provider == 'egaSSO':
+            # As example, this line request a GET to base_url + '/' + userDetails with Bearer  Authentication,
+    # and expects that authorization server checks the token, and response with user details
+            me = self.appbuilder.sm.oauth_remotes[provider].get('userDetails').data
+            logging.debug("user_data: {0}".format(me))
+            return { 'name' : me['name'], 'email' : me['email'], 'id' : me['user_name'], 'username' : me['user_name'], 'first_name':'', 'last_name':''}
+    ...
+```
+
+This file must be located at the same directory than `superset_config.py` with the name
+`custom_sso_security_manager.py`. Finally, add the following 2 lines to `superset_config.py`:
+
+```
+from custom_sso_security_manager import CustomSsoSecurityManager
+CUSTOM_SECURITY_MANAGER = CustomSsoSecurityManager
+```
+
+### Feature Flags
+
+To support a diverse set of users, Superset has some features that are not enabled by default. For
+example, some users have stronger security restrictions, while some others may not. So Superset
+allow users to enable or disable some features by config. For feature owners, you can add optional
+functionalities in Superset, but will be only affected by a subset of users.
+
+You can enable or disable features with flag from `superset_config.py`:
+
+```python
+DEFAULT_FEATURE_FLAGS = {
+    'CLIENT_CACHE': False,
+    'ENABLE_EXPLORE_JSON_CSRF_PROTECTION': False,
+    'PRESTO_EXPAND_DATA': False,
+}
+```
+
+Here is a list of flags and descriptions:
+
+- `ENABLE_EXPLORE_JSON_CSRF_PROTECTION`: For some security concerns, you may need to enforce CSRF
+  protection on all query request to the `explore_json` endpoint. When
+  `ENABLE_EXPLORE_JSON_CSRF_PROTECTION` is set to true, your users cannot make GET request to
+  `explore_json`. The default value for this feature is `False` and `explore_json` will accept both
+  GET and POST request. See [PR 7935](https://github.com/apache/incubator-superset/pull/7935) for
+  more details.
+
+- `PRESTO_EXPAND_DATA`: When this feature is enabled, nested types in Presto will be expanded into
+  extra columns and / or arrays. This is experimental, and doesn’t work with all nested types.
+
+### SIP 15
+
+[Superset Improvement Proposal 15](https://github.com/apache/incubator-superset/issues/6360) aims to
+ensure that time intervals are handled in a consistent and transparent manner for both the Druid and
+SQLAlchemy connectors.
+
+Prior to SIP-15 SQLAlchemy used inclusive endpoints however these may behave like exclusive for
+string columns (due to lexicographical ordering) if no formatting was defined and the column
+formatting did not conform to an ISO 8601 date-time (refer to the SIP for details).
+
+To remedy this rather than having to define the date/time format for every non-IS0 8601 date-time
+column, once can define a default column mapping on a per database level via the `extra` parameter:
+
+```

Review comment:
       ```suggestion
   ```python
   ```




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org