Source code for dgenerate.batchprocess.configrunnerplugin

# Copyright (c) 2023, Teriks
#
# dgenerate is distributed under the following BSD 3-Clause License
#
# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in
#    the documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived
#    from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import collections.abc
import typing

import dgenerate
import dgenerate.batchprocess.configrunnerpluginloader as _configrunnerpluginloader
import dgenerate.plugin as _plugin
import dgenerate.renderloop as _renderloop
import dgenerate.types as _types


[docs] class ConfigRunnerPlugin(_plugin.Plugin): """ Abstract base class for config runner plugin implementations. """
[docs] def __init__(self, loaded_by_name: str, config_runner: typing.Optional['dgenerate.batchprocess.ConfigRunner'] = None, render_loop: typing.Optional[_renderloop.RenderLoop] = None, local_files_only: bool = False, **kwargs): super().__init__(loaded_by_name=loaded_by_name, argument_error_type=_configrunnerpluginloader.ConfigRunnerPluginArgumentError, **kwargs) self.__config_runner = config_runner self.__render_loop = render_loop self.__local_files_only = local_files_only
[docs] def set_template_variable(self, name, value): """ Set a template variable on the :py:class:`dgenerate.batchprocess.ConfigRunner` instance. :param name: variable name :param value: variable value """ if self.config_runner is not None: self.config_runner.template_variables[name] = value
[docs] def update_template_variables(self, values): """ Update multiple template variable values on the :py:class:`dgenerate.batchprocess.ConfigRunner` instance. :param values: variable values, dictionary of names to values """ if self.config_runner is not None: self.config_runner.template_variables.update(values)
[docs] def register_directive(self, name, implementation: typing.Callable[[collections.abc.Sequence[str]], int]): """ Register a config directive implementation on the :py:class:`dgenerate.batchprocess.ConfigRunner` instance. Your directive should return a return code, 0 for success and anything else for failure. Returning non zero will cause :py:class:`BatchProcessError` to be raised from the runner, halting execution of the config. Any non-exiting exception will be eaten and rethrown as :py:class:`BatchProcessError`, also halting execution of the config. :raise RuntimeError: if a config directive with the same name already exists :param name: directive name :param implementation: implementation callable """ if self.config_runner is not None: if name in self.config_runner.directives: raise RuntimeError( f'directive name "{name}" cannot be registered by plugin ' f'"{self.loaded_by_name}" because that directive name already exists.') self.config_runner.directives[name] = implementation
[docs] def register_template_function(self, name, implementation: typing.Callable): """ Register a config template function implementation on the :py:class:`dgenerate.batchprocess.ConfigRunner` instance. :raise RuntimeError: if a template function with the same name already exists :param name: function name :param implementation: implementation callable """ if self.config_runner is not None: if name in self.config_runner.template_functions: raise RuntimeError( f'template function name "{name}" cannot be registered by plugin ' f'"{self.loaded_by_name}" because that template function name already exists.') self.config_runner.template_functions[name] = implementation
@property def injected_args(self) -> collections.abc.Sequence[str]: """ Return any arguments injected into the config from the command line. If none were injected an empty sequence will be returned. :return: command line arguments """ if self.config_runner is not None: return self.config_runner.injected_args return [] @property def render_loop(self) -> _renderloop.RenderLoop | None: """ Provides access to the currently instantiated :py:class:`dgenerate.renderloop.RenderLoop` object. This object will have been used for any previous invocation of dgenerate in a config file. """ return self.__render_loop @property def config_runner(self) -> typing.Optional['dgenerate.batchprocess.ConfigRunner']: """ Provides access to the currently instantiated :py:class:`dgenerate.batchprocess.ConfigRunner` object running the config file that this directive is being invoked in. """ return self.__config_runner @property def plugin_module_paths(self) -> frozenset[str]: """ Set of plugin module paths if they were injected into the config runner by ``--plugin-modules`` or used in a ``\\import_plugins`` statement in a config. :return: a set of paths, may be empty but not ``None`` """ if self.config_runner is not None: return self.config_runner.plugin_module_paths return frozenset() @property def local_files_only(self) -> bool: """ Is this plugin only going to look for resources such as models in cache / on disk? """ return self.__local_files_only
__all__ = _types.module_all()