samtranslator/feature_toggle/dialup.py (33 lines of code) (raw):
import hashlib
from abc import ABC, abstractmethod
class BaseDialup(ABC):
"""BaseDialup class to provide an interface for all dialup classes"""
def __init__(self, region_config, **kwargs) -> None: # type: ignore[no-untyped-def]
self.region_config = region_config
@abstractmethod
def is_enabled(self) -> bool:
"""
Returns a bool on whether this dialup is enabled or not
"""
def __str__(self) -> str:
return self.__class__.__name__
class DisabledDialup(BaseDialup):
"""
A dialup that is never enabled
"""
def __init__(self, region_config, **kwargs) -> None: # type: ignore[no-untyped-def]
super().__init__(region_config)
def is_enabled(self) -> bool:
return False
class ToggleDialup(BaseDialup):
"""
A simple toggle Dialup
Example of region_config: { "type": "toggle", "enabled": True }
"""
def __init__(self, region_config, **kwargs) -> None: # type: ignore[no-untyped-def]
super().__init__(region_config)
self.region_config = region_config
def is_enabled(self): # type: ignore[no-untyped-def]
return self.region_config.get("enabled", False)
class SimpleAccountPercentileDialup(BaseDialup):
"""
Simple account percentile dialup, enabling X% of
Example of region_config: { "type": "account-percentile", "enabled-%": 20 }
"""
def __init__(self, region_config, account_id, feature_name, **kwargs) -> None: # type: ignore[no-untyped-def]
super().__init__(region_config)
self.account_id = account_id
self.feature_name = feature_name
def _get_account_percentile(self) -> int:
"""
Get account percentile based on sha256 hash of account ID and feature_name
:returns: integer n, where 0 <= n < 100
"""
m = hashlib.sha256()
m.update(self.account_id.encode())
m.update(self.feature_name.encode())
return int(m.hexdigest(), 16) % 100
def is_enabled(self) -> bool:
"""
Enable when account_percentile falls within target_percentile
Meaning only (target_percentile)% of accounts will be enabled
"""
target_percentile: int = self.region_config.get("enabled-%", 0)
return self._get_account_percentile() < target_percentile