Feature Flag Management System in Python
Feature flags (also known as feature toggles) are a powerful technique for enabling or disabling features in your application without deploying new code. This challenge asks you to implement a basic feature flag management system in Python, allowing you to control feature availability based on a configuration. This is useful for A/B testing, gradual rollouts, and emergency feature disabling.
Problem Description
You need to create a FeatureFlagManager class that handles feature flag configurations and provides a method to check if a feature is enabled for a given user. The configuration will be stored in a dictionary where keys are feature flag names (strings) and values are dictionaries containing the flag's status ("enabled" or "disabled") and optionally, a list of user IDs for whom the feature is specifically enabled.
The check_feature method should return True if the feature is enabled for the given user, and False otherwise. The logic should follow these rules:
- Default State: If a feature flag is not present in the configuration, it should be considered disabled.
- Explicit Enable/Disable: If a feature flag exists, its
enabledstatus dictates its state. - User-Specific Enable: If a feature flag has a
user_idslist, the feature is enabled only for users present in that list. If the user is not in the list, theenabledstatus in the configuration dictates the state. - Case-Insensitive User ID Matching: User ID matching should be case-insensitive.
Examples
Example 1:
Input:
config = {
"new_feature": {"enabled": True, "user_ids": ["user1", "user2"]},
"old_feature": {"enabled": False}
}
user_id = "user1"
Output: True
Explanation: "new_feature" is enabled and "user1" is in the user_ids list.
Example 2:
Input:
config = {
"new_feature": {"enabled": True, "user_ids": ["user1", "user2"]},
"old_feature": {"enabled": False}
}
user_id = "user3"
Output: False
Explanation: "new_feature" is enabled, but "user3" is not in the user_ids list, so the default enabled status is checked.
Example 3:
Input:
config = {
"new_feature": {"enabled": True, "user_ids": ["user1", "user2"]},
"old_feature": {"enabled": False}
}
user_id = "USER1"
Output: True
Explanation: User ID matching is case-insensitive.
Example 4:
Input:
config = {}
user_id = "any_user"
Output: False
Explanation: The feature flag "any_feature" does not exist in the configuration, so it's considered disabled.
Constraints
- The
configdictionary will contain strings as keys (feature flag names) and dictionaries as values. - The inner dictionaries will contain keys
"enabled"(boolean) and optionally"user_ids"(list of strings). user_idswill be a list of strings, or an empty list.enabledwill always be a boolean.- The
user_idwill be a string. - The solution should be reasonably efficient for a small number of feature flags (less than 100). Performance is not a primary concern for this challenge.
Notes
- Consider using a class to encapsulate the feature flag management logic.
- Think about how to handle cases where the configuration is missing or invalid. For simplicity, you can assume the configuration is always valid in this challenge.
- Focus on clear and readable code.
- The
enabledstatus in the configuration is a boolean value (True or False). - User ID matching should be case-insensitive.