"""Get feature flags on backend.""" from oto import status as response_code from owsfeatures import features from owsrequest import request from masters_registry import config from masters_registry.constant import api_const from masters_registry.constant import field_const class OwsFeaturesError(Exception): """Raised when we failed to get features.""" def __str__(self): return 'Failed to load features from ows-features.' def _is_feature_enabled( feature_name, orchard_user_id=None, daemon=False, correlation_id=None): """Wrapper to handle both flask and daemon modes. Currently ows-features support only Flask apps. If we want to check for feature from something like Celery process, we need to send request directly to ows-features API. Args: feature_name (str): Name of feature to check orchard_user_id (str): Id of user to check features for daemon (bool): Whether feature requested from daemon process correlation_id (str): correlation id for logs, optional Returns: bool: Whether feature flag enabled """ if not daemon: return features.is_feature_enabled(feature_name) if orchard_user_id: prefix = orchard_user_id.split(':')[0] if prefix not in field_const.USER_ID_PREFIXES: orchard_user_id = '{prefix}{user_id}'.format( prefix=field_const.OA_USER_ID_PREFIX, user_id=orchard_user_id) user_features_dict = _get_user_features(orchard_user_id, correlation_id) return user_features_dict.get(feature_name) == 'enabled' def _get_user_features(orchard_user_id=None, correlation_id=None): """Fallback function for processes that don't use Flask, i.e. Celery. Args: orchard_user_id (str): identifier for user, e.g. alw:1234 correlation_id (str): correlation id for logs, optional Returns: dict: features for given user """ if orchard_user_id: url = '/features/user/{user_id}'.format(user_id=orchard_user_id) else: url = '/features' request_args = { 'application': config.SERVICE_NAME, 'environment': config.ENVIRONMENT, 'method': 'GET', 'service_name': api_const.OWS_FEATURES, 'path': url, 'correlation_id': correlation_id } features_response = request.process(**request_args) error_message = ( "Can't fetch features for user {0}. Response content: {1}" "Headers: {2}") if features_response.status_code != response_code.OK: error_message = error_message.format( orchard_user_id, features_response.content, features_response.headers) raise OwsFeaturesError(error_message) features_dict = features_response.json() return features_dict