def get_config_template(): return { 'enabled': confuse.TypeTemplate(bool), 'keywords': confuse.StrSeq(), 'max_following': confuse.Integer(), 'multiple': confuse.TypeTemplate(bool) }
def test_validate_good_choice_in_list(self): config = _root({'foo': 2}) valid = config['foo'].get( confuse.OneOf([ confuse.String(), confuse.Integer(), ])) self.assertEqual(valid, 2)
def test_validate_first_good_choice_in_list(self): config = _root({'foo': 3.14}) valid = config['foo'].get( confuse.OneOf([ confuse.Integer(), confuse.Number(), ])) self.assertEqual(valid, 3)
def test_validate_no_choice_in_list(self): config = _root({'foo': None}) with self.assertRaises(confuse.ConfigValueError): config['foo'].get( confuse.OneOf([ confuse.String(), confuse.Integer(), ]))
def get_config_template(): return { 'enabled': confuse.TypeTemplate(bool), 'host': confuse.String(), 'port': confuse.Integer(), 'tls': confuse.TypeTemplate(bool), 'username': confuse.String(), 'password': confuse.String(), 'recipient': confuse.String() }
def test_nested_attribute_access(self): config = _root({ 'foo': { 'bar': 8 }, }) valid = config.get({ 'foo': { 'bar': confuse.Integer() }, }) self.assertEqual(valid.foo.bar, 8)
def test_nested_dict_template(self): config = _root({ 'foo': { 'bar': 9 }, }) valid = config.get({ 'foo': { 'bar': confuse.Integer() }, }) self.assertEqual(valid['foo']['bar'], 9)
async def main(): log_levels = ['CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG'] config_template = { 'devices': confuse.Sequence(BluetoothDeviceConfuseTemplate(), ), 'log_level': confuse.Choice(log_levels, default=DEFAULT_LOG_LEVEL), 'mqtt': { 'enabled': confuse.Choice([True, False], default=DEFAULT_MQTT_ENABLED), 'host': confuse.String(default=DEFAULT_MQTT_HOST), 'log_level': confuse.Choice(['ERROR', 'WARNING', 'INFO', 'DEBUG'], default=DEFAULT_MQTT_LOG_LEVEL), 'port': confuse.Integer(default=DEFAULT_MQTT_PORT), 'protocol': confuse.String(default=DEFAULT_MQTT_PROTOCOL), }, 'scheduler': { 'log_level': confuse.Choice(log_levels, default=DEFAULT_SCHEDULER_LOG_LEVEL), }, } config = confuse.Configuration('bluetooth_tracker', __name__).get(config_template) kwargs = {} kwargs['bluetooth_rssi_scanner'] = FakeBluetoothScanner kwargs['bluetooth_lookup_name_func'] = lambda *_: 'test' detector = Detector( config, mqtt.Client(), AsyncIOScheduler(), **kwargs, ) detector.start_detecting() killer = GracefulKiller() while not killer.kill_now: await asyncio.sleep(1) logging.info('shutting down') detector.stop_detecting()
def test_optional_mapping_template_allow_missing_no_explicit_default(self): config = _root({}) template = {'bar': confuse.Integer(), 'baz': confuse.String()} valid = config.get({'foo': confuse.Optional(template)}) self.assertIsNone(valid['foo'])
def test_wrong_type_raises_error_on_validate(self): config = _root({'foo': 'bar'}) with self.assertRaises(confuse.ConfigTypeError): config.get({'foo': confuse.Integer()})
def test_optional_mapping_template_invalid(self): config = _root({'foo': {'bar': 5, 'baz': 10}}) template = {'bar': confuse.Integer(), 'baz': confuse.String()} with self.assertRaises(confuse.ConfigTypeError): config.get({'foo': confuse.Optional(template)})
def test_optional_mapping_template_valid(self): config = _root({'foo': {'bar': 5, 'baz': 'bak'}}) template = {'bar': confuse.Integer(), 'baz': confuse.String()} valid = config.get({'foo': confuse.Optional(template)}) self.assertEqual(valid['foo']['bar'], 5) self.assertEqual(valid['foo']['baz'], 'bak')
def test_none_as_default(self): config = _root({}) valid = config.get({'foo': confuse.Integer(None)}) self.assertIsNone(valid['foo'])
def test_validate_simple_dict(self): config = _root({'foo': 5}) valid = config.get({'foo': confuse.Integer()}) self.assertEqual(valid['foo'], 5)
def test_optional_mapping_template_null_missing_not_allowed(self): config = _root({'foo': None}) template = {'bar': confuse.Integer(), 'baz': confuse.String()} valid = config.get( {'foo': confuse.Optional(template, allow_missing=False)}) self.assertIsNone(valid['foo'])
"make_label": confuse.Choice(choices=[True, False], default=False), "uve_type": confuse.String(), "uve_module": confuse.String(), "uve_instances": confuse.StrSeq(default=[]), "json_path": confuse.String(), "append_field_name": confuse.Choice(choices=[True, False], default=True), "labels_from_path": Dict(default={}), } _global_template = { "analytics": { "host": confuse.String(pattern=r"^https?://"), "base_url": confuse.String(pattern=r"^/", default="/analytics/uves"), }, "prometheus": { "port": confuse.Integer(default=8080), "metric_name_prefix": confuse.String(default="tungsten"), }, "scraper": { "max_retry": confuse.Integer(default=3), "timeout": confuse.Integer(default=1), "pool_size": confuse.Integer(default=10), "interval": confuse.Integer(default=60), }, "logging": { "level": confuse.Choice(choices=["DEBUG", "INFO", "WARNING", "ERROR"], default="INFO") }, "metrics": confuse.Sequence(_metric_template), }
def test_undeclared_key_raises_keyerror(self): config = _root({'foo': 5}) valid = config.get({'foo': confuse.Integer()}) with self.assertRaises(KeyError): valid['bar']
class Config: template = { 'twitter': { 'consumer_key': confuse.String(), 'consumer_secret': confuse.String(), 'access_token_key': confuse.String(), 'access_token_secret': confuse.String(), 'min_ratelimit_percent': confuse.Integer(), 'search': { 'queries': confuse.TypeTemplate(list), 'max_queue': confuse.Integer(), 'max_quote_depth': confuse.Integer(), 'min_quote_similarity': confuse.Number(), 'skip_retweeted': confuse.TypeTemplate(bool), 'filter': { 'min_retweets': { 'enabled': confuse.TypeTemplate(bool), 'number': confuse.Integer() } }, 'sort': { 'by_keywords': { 'enabled': confuse.TypeTemplate(bool), 'keywords': confuse.StrSeq() }, 'by_age': { 'enabled': confuse.TypeTemplate(bool), }, 'by_retweets_count': { 'enabled': confuse.TypeTemplate(bool), } } }, 'actions': { 'follow': { 'enabled': confuse.TypeTemplate(bool), 'keywords': confuse.StrSeq(), 'max_following': confuse.Integer(), 'multiple': confuse.TypeTemplate(bool) }, 'favorite': { 'enabled': confuse.TypeTemplate(bool), 'keywords': confuse.StrSeq() }, 'tag_friend': { 'enabled': confuse.TypeTemplate(bool), 'friends': confuse.StrSeq(), } }, 'scheduler': { 'search_interval': confuse.Integer(), 'retweet_interval': confuse.Integer(), 'retweet_random_margin': confuse.Integer(), 'blocked_users_update_interval': confuse.Integer(), 'clear_queue_interval': confuse.Integer(), 'rate_limit_update_interval': confuse.Integer(), 'check_mentions_interval': confuse.Integer(), }, }, 'notifiers': { 'mail': { 'enabled': confuse.TypeTemplate(bool), 'host': confuse.String(), 'port': confuse.Integer(), 'tls': confuse.TypeTemplate(bool), 'username': confuse.String(), 'password': confuse.String(), 'recipient': confuse.String() }, 'pushbullet': { 'enabled': confuse.TypeTemplate(bool), 'token': confuse.String() } } } _valid = None @staticmethod def get(): """ Gets the static config object :return: """ if Config._valid is None: raise ValueError("Configuration not loaded") return Config._valid @staticmethod def load(filename=None): """ Loads a file and imports the settings :param filename: the file to import """ config = confuse.LazyConfig('Yatcobot', __name__) # Add default config when in egg (using this way because egg is breaking the default way) if len(config.sources) == 0: default_config_text = pkg_resources.resource_string("yatcobot", "config_default.yaml") default_config = confuse.ConfigSource(yaml.load(default_config_text, Loader=confuse.Loader), 'pkg/config_default.yaml', True) config.add(default_config) # Add user specified config if filename is not None and os.path.isfile(filename): config.set_file(filename) logger.info('Loading config files (From highest priority to lowest):') for i, config_source in enumerate(config.sources): logger.info('{}: Path: {}'.format(i, config_source.filename)) Config._valid = config.get(Config.template)
def test_default_value(self): config = _root({}) valid = config.get({'foo': confuse.Integer(8)}) self.assertEqual(valid['foo'], 8)
def test_optional_mapping_template_allow_missing_default_value(self): config = _root({}) template = {'bar': confuse.Integer(), 'baz': confuse.String()} valid = config.get({'foo': confuse.Optional(template, {})}) self.assertIsInstance(valid['foo'], dict)
import confuse configuration_path_env_var = "REDIRECTORY_CONFIG_DIR" configuration_template = { "deployment": confuse.Choice(["prod", "dev", "test"]), "log_level": confuse.Choice(["debug", "info", "warning", "error", "critical"]), "node_type": confuse.Choice(["management", "worker", "compiler"]), "directories": { "data": confuse.String(), "ui": confuse.String() }, "service": { "ip": confuse.String(), "port": confuse.Integer(), "metrics_port": confuse.Integer() }, "database": { "type": confuse.Choice(["sqlite", "mysql"]), "path": confuse.String(default="redirectory_sqlite.db"), "host": confuse.String(default="localhost"), "port": confuse.Integer(default=3306), "name": confuse.String(default="redirectory"), "username": confuse.String(default="user"), "password": confuse.String(default="pass") }, "hyperscan": { "domain_db": confuse.String(default="hs_compiled_domain.hsd"), "rules_db": confuse.String(default="hs_compiled_rules.hsd") },
def test_optional_mapping_template_missing_not_allowed(self): config = _root({}) template = {'bar': confuse.Integer(), 'baz': confuse.String()} with self.assertRaises(confuse.NotFoundError): config.get( {'foo': confuse.Optional(template, allow_missing=False)})
def test_missing_required_value_raises_error_on_validate(self): config = _root({}) with self.assertRaises(confuse.NotFoundError): config.get({'foo': confuse.Integer()})
def test_validate_individual_value(self): config = _root({'foo': 5}) valid = config['foo'].get(confuse.Integer()) self.assertEqual(valid, 5)
import confuse _config = confuse.Configuration('traktor_ice', __name__) _template = { 'icecast': { 'source': { 'user': confuse.String(default='source'), 'password': confuse.String(default='hackme'), }, 'admin': { 'user': confuse.String(default='admin'), 'password': confuse.String(default='hackme'), }, 'port': confuse.Integer(default=8000), 'server': confuse.String(default='localhost'), }, 'stream': { 'title': confuse.String(default='Stream Title'), 'description': confuse.String(default='Stream description'), 'genre': confuse.String(default='Stream Genre'), 'url': confuse.String(default='http://localhost'), }, 'traktor': { 'recordings-path': confuse.Path(), 'recordings-extension': confuse.String(default='wav') }, 'nowplaying': { 'port': confuse.Integer(default=8001) } }
def test_undeclared_key_ignored_from_input(self): config = _root({'foo': 5, 'bar': 6}) valid = config.get({'foo': confuse.Integer()}) with self.assertRaises(KeyError): valid['bar']
def test_attribute_access(self): config = _root({'foo': 5}) valid = config.get({'foo': confuse.Integer()}) self.assertEqual(valid.foo, 5)
class Config: base_template = { 'twitter': { 'consumer_key': confuse.String(), 'consumer_secret': confuse.String(), 'access_token_key': confuse.String(), 'access_token_secret': confuse.String(), 'min_ratelimit_percent': confuse.Integer(), 'search': { 'queries': confuse.TypeTemplate(list), 'max_queue': confuse.Integer(), 'max_quote_depth': confuse.Integer(), 'min_quote_similarity': confuse.Number(), 'skip_retweeted': confuse.TypeTemplate(bool), # Is updated on runtime 'filter': {}, # Is updated on runtime 'sort': {}, }, # Is updated on runtime 'actions': {}, 'scheduler': { 'search_interval': confuse.Integer(), 'retweet_interval': confuse.Integer(), 'retweet_random_margin': confuse.Integer(), 'blocked_users_update_interval': confuse.Integer(), 'clear_queue_interval': confuse.Integer(), 'rate_limit_update_interval': confuse.Integer(), 'check_mentions_interval': confuse.Integer(), }, }, # Is updated on runtime 'notifiers': {} } _valid = None @staticmethod def get(): """ Gets the static config object :return: """ if Config._valid is None: raise ValueError("Configuration not loaded") return Config._valid @staticmethod def load(filename=None): """ Loads a file and imports the settings :param filename: the file to import """ config = confuse.LazyConfig('Yatcobot', __name__) # Add default config when in egg (using this way because egg is breaking the default way) if len(config.sources) == 0: default_config_text = pkg_resources.resource_string("yatcobot.config", "config_default.yaml") default_config = confuse.ConfigSource(yaml.load(default_config_text, Loader=confuse.Loader), 'pkg/config/config_default.yaml', True) config.add(default_config) # Add user specified config if filename is not None and os.path.isfile(filename): config.set_file(filename) logger.info('Loading config files (From highest priority to lowest):') config.resolve() for i, config_source in enumerate(config.sources): logger.info(f'{i}: Path: {config_source.filename}') # Update template from plugins template = Config.get_template() Config._valid = config.get(template) @staticmethod def get_template(): """ Updates the config template dynamically from plugins :return: config template """ template = Config.base_template # Merge filters templates from yatcobot.plugins.filters import FilterABC template['twitter']['search']['filter'].update(FilterABC.get_config_template()) # Merge ratings templates from yatcobot.plugins.ratings import RatingABC template['twitter']['search']['sort'].update(RatingABC.get_config_template()) # Merge actions templates from yatcobot.plugins.actions import ActionABC template['twitter']['actions'].update(ActionABC.get_config_template()) # Merge notifiers templates from yatcobot.plugins.notifiers import NotifierABC template['notifiers'].update(NotifierABC.get_config_template()) return template
def get_config_template(): return { 'enabled': confuse.TypeTemplate(bool), 'number': confuse.Integer() }