feat(feature_flag): Provide user with ability to override feature flags

ref: #693 #493 #575
This commit is contained in:
2025-03-22 14:40:41 +09:30
parent b34c76afde
commit e6f576ef1a
9 changed files with 49 additions and 2 deletions

View File

@ -69,6 +69,7 @@ CELERY_TASK_SEND_SENT_EVENT = True
CELERY_WORKER_SEND_TASK_EVENTS = True # worker_send_task_events
FEATURE_FLAGGING_ENABLED = True # Turn Feature Flagging on/off
FEATURE_FLAG_OVERRIDES = None # Feature Flags to override fetched feature flags
# PROMETHEUS_METRICS_EXPORT_PORT_RANGE = range(8010, 8010)
# PROMETHEUS_METRICS_EXPORT_PORT = 8010
@ -488,5 +489,12 @@ if FEATURE_FLAGGING_ENABLED:
'cache_dir': str(BASE_DIR) + '/',
'disable_downloading': False,
'unique_id': unique_id,
'version': feature_flag_version
'version': feature_flag_version,
}
if FEATURE_FLAG_OVERRIDES:
feature_flag.update({
'over_rides': FEATURE_FLAG_OVERRIDES
})

View File

@ -14,6 +14,7 @@ feature_flag = {
'disable_downloading': False # Prevent downloading feature flags
'unique_id': 'unique ID for application', # Unique ID for this instance of your Django application
'version': '1.0.0', # The Version of Your Django Application
'over_rides': [] # list(dict). Feature Flag over rides. use same format as API endpoint.
} # Note: All key values are strings
```

View File

@ -76,6 +76,9 @@ class CenturionFeatureFlagging:
_last_modified: datetime = None
""" Last modified date/time of the feature flags"""
_over_rides: dict = None
"""Feature Flag Over rides."""
_response: requests.Response = None
"""Cached response from fetched feature flags"""
@ -95,6 +98,7 @@ class CenturionFeatureFlagging:
disable_downloading: bool = False,
unique_id: str = None,
version: str = None,
over_rides: dict = None,
):
if not str(cache_dir).endswith('/'):
@ -108,6 +112,21 @@ class CenturionFeatureFlagging:
self._disable_downloading = disable_downloading
if over_rides:
_over_rides: dict = {}
for entry in over_rides:
[*key], [*flag] = zip(*entry.items())
_over_rides.update({
key[0]: FeatureFlag(key[0], flag[0])
})
self._over_rides = _over_rides
if version is None:
@ -174,6 +193,7 @@ class CenturionFeatureFlagging:
if(
self._feature_flags.get(key, None) is None
and self._over_rides.get(key, None) is None
and raise_exceptions
):
@ -182,10 +202,19 @@ class CenturionFeatureFlagging:
elif(
not raise_exceptions
and self._feature_flags.get(key, None) is None
and self._over_rides.get(key, None) is None
):
return False
elif(
not raise_exceptions
and self._over_rides.get(key, None) is not None
):
return self._over_rides[key]
return self._feature_flags[key]

View File

@ -27,6 +27,7 @@ class Command(BaseCommand):
disable_downloading = settings.feature_flag.get('disable_downloading', False),
unique_id = settings.feature_flag.get('unique_id', None),
version = settings.feature_flag.get('version', None),
over_rides = settings.feature_flag.get('over_rides', None),
)
self.stdout.write('Fetching Feature Flags.....')

View File

@ -21,6 +21,7 @@ class FeatureFlagMiddleware:
disable_downloading = settings.feature_flag.get('disable_downloading', False),
unique_id = settings.feature_flag.get('unique_id', None),
version = settings.feature_flag.get('version', None),
over_rides = settings.feature_flag.get('over_rides', None),
)

View File

@ -24,6 +24,7 @@ if getattr(settings,'feature_flag', None):
disable_downloading = settings.feature_flag.get('disable_downloading', False),
unique_id = settings.feature_flag.get('unique_id', None),
version = settings.feature_flag.get('version', None),
over_rides = settings.feature_flag.get('over_rides', None),
)
_feature_flagging.get()

View File

@ -55,6 +55,7 @@ class APIRootView(
disable_downloading = settings.feature_flag.get('disable_downloading', False),
unique_id = settings.feature_flag.get('unique_id', None),
version = settings.feature_flag.get('version', None),
over_rides = settings.feature_flag.get('over_rides', None),
)
@ -77,6 +78,7 @@ class SimpleRouter(
disable_downloading = settings.feature_flag.get('disable_downloading', False),
unique_id = settings.feature_flag.get('unique_id', None),
version = settings.feature_flag.get('version', None),
over_rides = settings.feature_flag.get('over_rides', None),
)
self._feature_flagging.get()
@ -103,6 +105,7 @@ class DefaultRouter(
disable_downloading = settings.feature_flag.get('disable_downloading', False),
unique_id = settings.feature_flag.get('unique_id', None),
version = settings.feature_flag.get('version', None),
over_rides = settings.feature_flag.get('over_rides', None),
)
self._feature_flagging.get()

View File

@ -30,4 +30,5 @@ Within your settings file the following settings are available
| Attribute | Type | Default | Description |
|:---|:---:|:---:|:---|
| FEATURE_FLAGGING_ENABLED | `Bolean` | `True `| Turn feature flagging on/off |
| FEATURE_FLAGGING_ENABLED | `Boolean` | `True `| Turn feature flagging on/off. |
| FEATURE_FLAG_OVERRIDES | `list(dict)` | `None` | Feature Flags to override. Uses same format as the API Enbdpoint. |

View File

@ -31,6 +31,8 @@ DATABASES = {
FEATURE_FLAGGING_ENABLED = True # Turn Feature Flagging on/off
FEATURE_FLAG_OVERRIDES = [] # Feature Flag Overrides. Takes preceedence over downloaded feature flags.
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
SECURE_SSL_REDIRECT = True