Skip to content

Commit

Permalink
Merge default feature flags and user defined feature flags
Browse files Browse the repository at this point in the history
- Rename the default feature flags key in `config.py` to DEFAULT_FEATURE_FLAGS
- Merge default feature flags with user defined ones allowing the latter to overwrite the former
- Expose feature_flags for both server and client to use
- Add a utility method for checking whether a feature flag is on on server side
  • Loading branch information
xtinec committed Jan 31, 2019
1 parent 817783f commit b70a9ae
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 5 deletions.
4 changes: 4 additions & 0 deletions CONTRIBUTING.md
Expand Up @@ -410,6 +410,10 @@ export enum FeatureFlag {
}
```

`superset/config.py` contains `DEFAULT_FEATURE_FLAGS` which will be overwritten by
those specified under FEATURE_FLAGS in `superset_config.py`. For example, `DEFAULT_FEATURE_FLAGS = { 'FOO': True, 'BAR': False }` in `superset/config.py` and `FEATURE_FLAGS = { 'BAR': True, 'BAZ': True }` in `superset_config.py` will result
in combined feature flags of `{ 'FOO': True, 'BAR': True, 'BAZ': True }`.

## Linting

Lint the project with:
Expand Down
4 changes: 4 additions & 0 deletions superset/__init__.py
Expand Up @@ -208,6 +208,10 @@ def index(self):

results_backend = app.config.get('RESULTS_BACKEND')

# Merge user defined feature flags with default feature flags
feature_flags = app.config.get('DEFAULT_FEATURE_FLAGS')
feature_flags.update(app.config.get('FEATURE_FLAGS') or {})

# Registering sources
module_datasource_map = app.config.get('DEFAULT_MODULE_DS_MAP')
module_datasource_map.update(app.config.get('ADDITIONAL_MODULE_DS_MAP'))
Expand Down
9 changes: 6 additions & 3 deletions superset/config.py
Expand Up @@ -186,9 +186,12 @@
# ---------------------------------------------------
# Feature flags
# ---------------------------------------------------
# Feature flags that are on by default go here. Their
# values can be overridden by those in super_config.py
FEATURE_FLAGS = {}
# Feature flags that are set by default go here. Their values can be
# overwritten by those specified under FEATURE_FLAGS in super_config.py
# For example, DEFAULT_FEATURE_FLAGS = { 'FOO': True, 'BAR': False } here
# and FEATURE_FLAGS = { 'BAR': True, 'BAZ': True } in superset_config.py
# will result in combined feature flags of { 'FOO': True, 'BAR': True, 'BAZ': True }
DEFAULT_FEATURE_FLAGS = {}

# ---------------------------------------------------
# Image and file configuration
Expand Down
25 changes: 25 additions & 0 deletions superset/utils/feature_flags.py
@@ -0,0 +1,25 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# pylint: disable=C,R,W
from superset import feature_flags


def is_feature_enabled(feature):
"""
Utility function for checking whether a feature is turned on
"""
return feature_flags.get(feature)
4 changes: 2 additions & 2 deletions superset/views/base.py
Expand Up @@ -31,7 +31,7 @@
import simplejson as json
import yaml

from superset import conf, db, security_manager
from superset import conf, db, feature_flags, security_manager
from superset.exceptions import SupersetException, SupersetSecurityException
from superset.translations.utils import get_language_pack
from superset.utils import core as utils
Expand Down Expand Up @@ -157,7 +157,7 @@ def common_bootsrap_payload(self):
'conf': {k: conf.get(k) for k in FRONTEND_CONF_KEYS},
'locale': locale,
'language_pack': get_language_pack(locale),
'feature_flags': conf.get('FEATURE_FLAGS'),
'feature_flags': feature_flags,
}


Expand Down
9 changes: 9 additions & 0 deletions tests/utils_tests.py
Expand Up @@ -39,6 +39,7 @@
zlib_compress,
zlib_decompress_to_string,
)
from superset.utils.feature_flags import is_feature_enabled


def mock_parse_human_datetime(s):
Expand Down Expand Up @@ -756,3 +757,11 @@ def test_convert_legacy_filters_into_adhoc_present_and_nonempty(self):
}
convert_legacy_filters_into_adhoc(form_data)
self.assertEquals(form_data, expected)

@patch.dict('superset.feature_flags', {'FOO': True}, clear=True)
def test_existing_feature_flags(self):
self.assertTrue(is_feature_enabled('FOO'))

@patch.dict('superset.feature_flags', {}, clear=True)
def test_nonexistent_feature_flags(self):
self.assertFalse(is_feature_enabled('FOO'))

0 comments on commit b70a9ae

Please sign in to comment.