def generate_app_logging(args: Sequence[str]): """Generate and save application logging configuration file. Args: args: Command line arguments --config-file: Configuration will be written to this file (will print to stdout if missing) --filename: Logs will be written to this file (if file logging is enabled) --level: Log level to use Returns: Logging configuration in dict form """ parser = ArgumentParser() parser.add_argument("--config-file", type=str, default=None) parser.add_argument("--level", type=str, default=None) parser.add_argument("--filename", type=str, default=None) parsed_args = vars(parser.parse_args(args)) logging_config = default_app_config( parsed_args.get("level"), parsed_args.get("filename") ) dump_data(logging_config, filename=parsed_args.get("config_file"), file_type="yaml") return logging_config
def teardown_function(function): os.environ = original_env yapconf.yaml = original_yaml real_world_path = os.path.join(current_dir, 'files', 'real_world') tmp_path = os.path.join(real_world_path, 'tmp') json_file = os.path.join(real_world_path, 'config_to_change.json') yaml_file = os.path.join(real_world_path, 'config_to_change.yaml') original_data = { 'database': { 'host': '1.2.3.4', 'name': 'myapp_prod', 'port': 3306, 'verbose': False, }, 'emoji': u'💩', 'file': '/path/to/file.yaml', 'ssl': { 'private_key': 'blah', 'public_key': 'blah', }, 'web_port': 443, } yapconf.dump_data(original_data, json_file, file_type='json') yapconf.dump_data(original_data, yaml_file, file_type='yaml') if os.path.exists(tmp_path): os.remove(tmp_path)
def change_config(label): if label == 'label1': config = real_world_spec.load_config('label1') config.database.port += 1 yapconf.dump_data(config.to_dict(), filename=yaml_filename, file_type='yaml') elif label == 'label2': config = real_world_spec.load_config('label2') config.database.port += 1 yapconf.dump_data(config.to_dict(), filename=json_filename, file_type='json') elif label == 'label3': safe_data['database']['port'] += 1
def test_dump_box(ascii_data): data = {'writes': ''} def mock_write(x): data['writes'] += x expected = ('db:{n}' ' name: db_name{n}' ' port: 123{n}' 'foo: bar{n}' 'items:{n}' '- 1{n}' '- 2{n}' '- 3{n}').format(n=os.linesep) boxed_data = Box(ascii_data) with patch('sys.stdout.write', mock_write): yapconf.dump_data(boxed_data, file_type='yaml') assert data['writes'] == expected
def generate_plugin_logging(args: Sequence[str]) -> dict: """Generate and save plugin logging configuration file. Args: args: Command line arguments --config-file: Plugin configuration will be written to this file (will print to stdout if missing) --stdout: Explicitly enable logging to stdout --no-stdout: Explicitly disable logging to stdout --file: Explicitly enable logging to a file --no-file: Explicitly disable logging to a file --filename: Logs will be written to this file (if file logging is enabled) --level: Log level to use Returns: Logging configuration in dict form """ parser = ArgumentParser() parser.add_argument("--config-file", type=str, default=None) parser.add_argument("--level", type=str, default=None) parser.add_argument("--filename", type=str, default=None) parser.add_argument("--stdout", dest="stdout", action="store_true") parser.add_argument("--no-stdout", dest="stdout", action="store_false") parser.add_argument("--file", dest="file", action="store_true") parser.add_argument("--no-file", dest="file", action="store_false") parsed_args = vars(parser.parse_args(args)) logging_config = default_plugin_config( level=parsed_args.get("level"), stdout=parsed_args.get("stdout"), file=parsed_args.get("file"), filename=parsed_args.get("filename"), ) dump_data(logging_config, filename=parsed_args.get("config_file"), file_type="yaml") return logging_config
def generate_config_file(spec, cli_args): """Generate a configuration file. Takes a specification and a series of command line arguments. Will create a file at the location specified by the resolved `config` value. If none exists the configuration will be printed to stdout. Args: spec (yapconf.YapconfSpec): Specification for the application cli_args (List[str]): Command line arguments Returns: None Raises: YapconfLoadError: Missing 'config' configuration option (file location) """ config = _generate_config(spec, cli_args) # Bootstrap items shouldn't be in the generated config file # We mimic a migration as it's the easiest way to filter out bootstrap items items = [ item for item in spec._yapconf_items.values() if not item.bootstrap ] filtered_config = {} for item in items: item.migrate_config(config, filtered_config, always_update=False, update_defaults=False) yapconf.dump_data( filtered_config, filename=config.configuration.file, file_type=_get_config_type(config), )
def generate(args: Sequence[str]): """Generate a configuration file. Takes a series of command line arguments and will create a file at the location specified by the resolved `configuration.file` value. If that value resolves to None the configuration will be printed to STDOUT. Note that bootstrap items will not be included in the generated configuration. Args: args: Command line arguments Returns: None Raises: YapconfLoadError: Missing 'config' configuration option (file location) """ spec, cli_vars = _parse_args(args) bootstrap = spec.load_filtered_config(cli_vars, "ENVIRONMENT", bootstrap=True) config = spec.load_filtered_config(cli_vars, "ENVIRONMENT", exclude_bootstrap=True) dump_data(config, filename=bootstrap.configuration.file, file_type="yaml")
def test_dump_data(tmpdir, data, file_type): path = tmpdir.join('test.%s' % file_type) filename = os.path.join(path.dirname, path.basename) yapconf.dump_data(data, filename, file_type) assert data == yapconf.load_file(filename, file_type)
def migrate_config_file( self, config_file_path, always_update=False, current_file_type=None, output_file_name=None, output_file_type=None, create=True, update_defaults=True, dump_kwargs=None, include_bootstrap=True, ): """Migrates a configuration file. This is used to help you update your configurations throughout the lifetime of your application. It is probably best explained through example. Examples: Assume we have a JSON config file ('/path/to/config.json') like the following: ``{"db_name": "test_db_name", "db_host": "1.2.3.4"}`` >>> spec = YapconfSpec({ ... 'db_name': { ... 'type': 'str', ... 'default': 'new_default', ... 'previous_defaults': ['test_db_name'] ... }, ... 'db_host': { ... 'type': 'str', ... 'previous_defaults': ['localhost'] ... } ... }) We can migrate that file quite easily with the spec object: >>> spec.migrate_config_file('/path/to/config.json') Will result in /path/to/config.json being overwritten: ``{"db_name": "new_default", "db_host": "1.2.3.4"}`` Args: config_file_path (str): The path to your current config always_update (bool): Always update values (even to None) current_file_type (str): Defaults to self._file_type output_file_name (str): Defaults to the current_file_path output_file_type (str): Defaults to self._file_type create (bool): Create the file if it doesn't exist (otherwise error if the file does not exist). update_defaults (bool): Update values that have a value set to something listed in the previous_defaults dump_kwargs (dict): A key-value pair that will be passed to dump include_bootstrap (bool): Include bootstrap items in the output Returns: box.Box: The newly migrated configuration. """ current_file_type = current_file_type or self._file_type output_file_type = output_file_type or self._file_type output_file_name = output_file_name or config_file_path current_config = self._get_config_if_exists( config_file_path, create, current_file_type ) migrated_config = {} if include_bootstrap: items = self._yapconf_items.values() else: items = [ item for item in self._yapconf_items.values() if not item.bootstrap ] for item in items: item.migrate_config( current_config, migrated_config, always_update, update_defaults ) if create: yapconf.dump_data( migrated_config, filename=output_file_name, file_type=output_file_type, klazz=YapconfLoadError, dump_kwargs=dump_kwargs, ) return Box(migrated_config)