Esempio n. 1
0
def run(configfile, unsafe: bool, loop: Optional[str], service: Optional[str]):
    # Read the configuration from the supplied YAML files
    config = {}  # type: Dict[str, Any]
    for path in configfile:
        config_data = yaml.load(path, Loader=Loader) if unsafe else yaml.safe_load(path)
        assert isinstance(config_data, dict), 'the document root element must be a dictionary'
        config = merge_config(config, config_data)

    # Override the event loop policy if specified
    if loop:
        config['event_loop_policy'] = loop

    services = config.pop('services', {})
    if not isinstance(services, dict):
        raise click.ClickException('The "services" key must be a dict, not {}'.format(
            qualified_name(services)))

    # If "component" was defined, use that as the default service if one has not been defined yet
    if 'component' in config:
        component = config.pop('component')
        services.setdefault('default', dict(component=component))

    # Try to figure out which service to launch
    service = service or os.getenv('ASPHALT_SERVICE')
    if len(services) == 0:
        raise click.ClickException('No services have been defined')
    elif service:
        try:
            service_config = services[service]
        except KeyError:
            raise click.ClickException(
                'Service {!r} has not been defined'.format(service)) from None
    elif len(services) == 1:
        service_config = next(iter(services.values()))
    elif 'default' in services:
        service_config = services['default']
    else:
        raise click.ClickException(
            'Multiple services present in configuration file but no default service has been '
            'defined and no service was explicitly selected with -s / --service')

    # Merge the service-level configuration with the top level one
    config = merge_config(config, service_config)

    # Start the application
    run_application(**config)
Esempio n. 2
0
def run(configfile, unsafe: bool, loop: Optional[str], service: Optional[str]):
    # Read the configuration from the supplied YAML files
    config = {}  # type: Dict[str, Any]
    for path in configfile:
        config_data = yaml.load(path, Loader=Loader if unsafe else SafeLoader)
        assert isinstance(config_data, dict), 'the document root element must be a dictionary'
        config = merge_config(config, config_data)

    # Override the event loop policy if specified
    if loop:
        config['event_loop_policy'] = loop

    services = config.pop('services', {})
    if not isinstance(services, dict):
        raise click.ClickException('The "services" key must be a dict, not {}'.format(
            qualified_name(services)))

    # If "component" was defined, use that as the default service if one has not been defined yet
    if 'component' in config:
        component = config.pop('component')
        services.setdefault('default', dict(component=component))

    # Try to figure out which service to launch
    service = service or os.getenv('ASPHALT_SERVICE')
    if len(services) == 0:
        raise click.ClickException('No services have been defined')
    elif service:
        try:
            service_config = services[service]
        except KeyError:
            raise click.ClickException(
                'Service {!r} has not been defined'.format(service)) from None
    elif len(services) == 1:
        service_config = next(iter(services.values()))
    elif 'default' in services:
        service_config = services['default']
    else:
        raise click.ClickException(
            'Multiple services present in configuration file but no default service has been '
            'defined and no service was explicitly selected with -s / --service')

    # Merge the service-level configuration with the top level one
    config = merge_config(config, service_config)

    # Start the application
    run_application(**config)
Esempio n. 3
0
def run(configfile, unsafe: bool, loop: Optional[str]):
    # Read the configuration from the supplied YAML files
    config = {}
    for path in configfile:
        config_data = yaml.load(path) if unsafe else yaml.safe_load(path)
        assert isinstance(config_data, dict), 'the document root element must be a dictionary'
        config = merge_config(config, config_data)

    # Override the event loop policy if specified
    if loop:
        config['event_loop_policy'] = loop

    # Start the application
    run_application(**config)
Esempio n. 4
0
def test_merge_config(overrides):
    original = {'a': 1, 'b': {'x': 2, 'y': 3, 'z': {'r': [1, 2], 's': [3, 4]}}}
    expected = {
        'a': 2,
        'foo': 6,
        'b': {
            'x': 5,
            'y': 3,
            'z': {
                'r': 'bar',
                's': [6, 7]
            }
        }
    }
    assert merge_config(original, overrides) == expected
Esempio n. 5
0
    def add_component(self,
                      alias: str,
                      type: Union[str, type] = None,
                      **config):
        """
        Add a child component.

        This will instantiate a component class, as specified by the ``type`` argument.

        If the second argument is omitted, the value of ``alias`` is used as its value.

        The locally given configuration can be overridden by component configuration parameters
        supplied to the constructor (via the ``components`` argument).

        When configuration values are provided both as keyword arguments to this method and
        component configuration through the ``components`` constructor argument, the configurations
        are merged together using :func:`~asphalt.core.util.merge_config` in a way that the
        configuration values from the ``components`` argument override the keyword arguments to
        this method.

        :param alias: a name for the component instance, unique within this container
        :param type: entry point name or :class:`Component` subclass or a ``module:varname``
            reference to one
        :param config: keyword arguments passed to the component's constructor

        """
        assert check_argument_types()
        if not isinstance(alias, str) or not alias:
            raise TypeError('component_alias must be a nonempty string')
        if alias in self.child_components:
            raise ValueError(
                'there is already a child component named "{}"'.format(alias))

        # Allow the external configuration to override the constructor arguments
        override_config = self.component_configs.get(alias) or {}
        config = merge_config(config, override_config)

        component = component_types.create_object(type or alias, **config)
        self.child_components[alias] = component
Esempio n. 6
0
    def add_component(self, alias: str, type: Union[str, type] = None, **config):
        """
        Add a child component.

        This will instantiate a component class, as specified by the ``type`` argument.

        If the second argument is omitted, the value of ``alias`` is used as its value.

        The locally given configuration can be overridden by component configuration parameters
        supplied to the constructor (via the ``components`` argument).

        When configuration values are provided both as keyword arguments to this method and
        component configuration through the ``components`` constructor argument, the configurations
        are merged together using :func:`~asphalt.core.util.merge_config` in a way that the
        configuration values from the ``components`` argument override the keyword arguments to
        this method.

        :param alias: a name for the component instance, unique within this container
        :param type: entry point name or :class:`Component` subclass or a ``module:varname``
            reference to one
        :param config: keyword arguments passed to the component's constructor

        """
        assert check_argument_types()
        if not isinstance(alias, str) or not alias:
            raise TypeError('component_alias must be a nonempty string')
        if alias in self.child_components:
            raise ValueError('there is already a child component named "{}"'.format(alias))

        config['type'] = type or alias

        # Allow the external configuration to override the constructor arguments
        override_config = self.component_configs.get(alias) or {}
        config = merge_config(config, override_config)

        component = component_types.create_object(**config)
        self.child_components[alias] = component
Esempio n. 7
0
def test_merge_config_none_args(original, overrides):
    assert merge_config(original, overrides) == {'a': 1}
Esempio n. 8
0
def test_merge_config(overrides):
    original = {'a': 1, 'b': {'x': 2, 'y': 3, 'z': {'r': [1, 2], 's': [3, 4]}}}
    expected = {'a': 2, 'foo': 6, 'b': {'x': 5, 'y': 3, 'z': {'r': 'bar', 's': [6, 7]}}}
    assert merge_config(original, overrides) == expected
Esempio n. 9
0
def test_merge_config_none_args(original, overrides):
    assert merge_config(original, overrides) == {'a': 1}