lembas package#

class lembas.Case(**kwargs)[source]#

Bases: object

Base case for all cases.

When constructing a new case, all assigned InputAttribute values can be set via keyword arguments.

property case_dir: Path | None#
property fully_resolved_name: str#

The fully-resolved import path of the case handler.

property inputs: dict[str, Any]#

A mapping of the name of each InputAttribute to its value.

static log(msg, *args, level=20)[source]#

Log a message to the logger.

Return type:

None

property relative_case_dir: Path | None#

Return a case directory relative to current working directory if possible.

If the case directory is not a subdirectory of current working directory, the absolute path is returned.

results: Results#
run()[source]#

Run the case.

If this method is not overridden, the default behavior is to run all the methods decorated with @step.

Return type:

None

class lembas.CaseList(cases=None)[source]#

Bases: Generic[TCase]

A generic collection of Case objects, and utility methods to create and run them.

Parameters:

cases (Iterable[TCase] | None) – An optional iterable of Case objects used to initialize the CaseList.

add(case)[source]#

Add a case to the list:

Parameters:

case (TypeVar(TCase, bound= Case)) – The case to add.

Return type:

TypeVar(TCase, bound= Case)

Returns:

The case that was added.

add_cases_by_parameter_sweep(case_class, **kwargs)[source]#

Add a number of cases by performing a parameter sweep using the Cartesian product.

Parameters:
  • case_class (type[TypeVar(TCase, bound= Case)]) – The type of case to construct.

  • kwargs (Any) – Any parameters to pass to the case constructors. If iterable values are provided, they will be used when performing the parameter sweep via itertools.product.

Return type:

None

run_all()[source]#

Run all the cases.

Return type:

None

class lembas.InputParameter(*, type=None, default=<class 'lembas.param._NoDefault'>, min=None, max=None, control=False)[source]#

Bases: object

An input parameter which can be defined for a Case, which determines case-specific values.

The parameter is of a defined type and type conversion will be performed when setting the value, if appropriate.

Parameters:
  • type (type | None) – The parameter type, e.g. float, str, etc.

  • default (Any) – The default value. If the type is not set, the type of the default will be used.

  • min (float | None) – The minimum value for the parameter (if it is a float).

  • max (float | None) – The maximum value for the parameter (if it is a float).

  • control (bool) – Set as True to indicate a runtime control parameter. These parameters will be excluded from the case.inputs dictionary.

property include_in_inputs_dict: bool#

If True, include the parameter in the case.inputs dictionary.

lembas.result(*func_or_names)[source]#

A decorator to annotate a method that provides result(s).

The decorator accepts a variadic list of names for the provided result(s). The method can return a single object or a tuple of objects, which must map to the number of names provided. The results are then available from within other case handler methods like self.results.result_name.

Return type:

RawCaseMethod | Callable[[RawCaseMethod], RawCaseMethod]

lembas.step(method=None, /, condition=None, requires=None)[source]#

A decorator to define steps to be performed when running a Case.

The step should not return a value.

Parameters:
  • method (RawCaseStepMethod | None) – The decorator may be used without any arguments, in which case the defaults will be used.

  • condition (Callable[[Any], bool] | str | None) – an optional callable which can be used to determine whether the step should run. It will receive the Case instance as its only argument, and must return a boolean which, if True, the step will run. Otherwise, it will be skipped. If a string is provided, the condition will be evaluated by performing an attribute lookup on the case, e.g. condition=”plot” evaluates to lambda case: case.plot. You may also place the word “not” in front of the attribute, e.g. condition=”not plot”, which evaluates to lambda case: not case.plot.

  • requires (str | Iterable[str] | None) – An iterable of dependent steps on which this one depends, or a single string.

Return type:

Any

Usage:
class MyCase(Case):
    @step(condition=lambda case: case.case_dir.exists())
    def some_analysis_step(self):
        # do something

Submodules#

lembas.case module#

class lembas.case.Case(**kwargs)[source]#

Bases: object

Base case for all cases.

When constructing a new case, all assigned InputAttribute values can be set via keyword arguments.

property case_dir: Path | None#
property fully_resolved_name: str#

The fully-resolved import path of the case handler.

property inputs: dict[str, Any]#

A mapping of the name of each InputAttribute to its value.

static log(msg, *args, level=20)[source]#

Log a message to the logger.

Return type:

None

property relative_case_dir: Path | None#

Return a case directory relative to current working directory if possible.

If the case directory is not a subdirectory of current working directory, the absolute path is returned.

results: Results#
run()[source]#

Run the case.

If this method is not overridden, the default behavior is to run all the methods decorated with @step.

Return type:

None

class lembas.case.CaseList(cases=None)[source]#

Bases: Generic[TCase]

A generic collection of Case objects, and utility methods to create and run them.

Parameters:

cases (Iterable[TCase] | None) – An optional iterable of Case objects used to initialize the CaseList.

add(case)[source]#

Add a case to the list:

Parameters:

case (TypeVar(TCase, bound= Case)) – The case to add.

Return type:

TypeVar(TCase, bound= Case)

Returns:

The case that was added.

add_cases_by_parameter_sweep(case_class, **kwargs)[source]#

Add a number of cases by performing a parameter sweep using the Cartesian product.

Parameters:
  • case_class (type[TypeVar(TCase, bound= Case)]) – The type of case to construct.

  • kwargs (Any) – Any parameters to pass to the case constructors. If iterable values are provided, they will be used when performing the parameter sweep via itertools.product.

Return type:

None

run_all()[source]#

Run all the cases.

Return type:

None

lembas.case.step(method=None, /, condition=None, requires=None)[source]#

A decorator to define steps to be performed when running a Case.

The step should not return a value.

Parameters:
  • method (RawCaseStepMethod | None) – The decorator may be used without any arguments, in which case the defaults will be used.

  • condition (Callable[[Any], bool] | str | None) – an optional callable which can be used to determine whether the step should run. It will receive the Case instance as its only argument, and must return a boolean which, if True, the step will run. Otherwise, it will be skipped. If a string is provided, the condition will be evaluated by performing an attribute lookup on the case, e.g. condition=”plot” evaluates to lambda case: case.plot. You may also place the word “not” in front of the attribute, e.g. condition=”not plot”, which evaluates to lambda case: not case.plot.

  • requires (str | Iterable[str] | None) – An iterable of dependent steps on which this one depends, or a single string.

Return type:

Any

Usage:
class MyCase(Case):
    @step(condition=lambda case: case.case_dir.exists())
    def some_analysis_step(self):
        # do something

lembas.cli module#

exception lembas.cli.Abort(msg='', *args, **kwargs)[source]#

Bases: Abort

Prints an optional message to the console, before aborting with non-zero exit code.

exception lembas.cli.Okay(msg='', *args, **kwargs)[source]#

Bases: Exit

Prints an optional message to the console, before cleanly exiting.

Provides a standard way to end/confirm a successful command.

exit_code: int#
lembas.cli.main(version=<typer.models.OptionInfo object>)[source]#

Command Line Interface for Lembas.

Return type:

None

lembas.cli.run(case_handler_name, params=<typer.models.ArgumentInfo object>, *, plugin=None)[source]#

Run a single case of a given case handler type.

Return type:

None

lembas.logging module#

lembas.param module#

Custom parameter types that can be defined on lembas.Case instances.

class lembas.param.InputParameter(*, type=None, default=<class 'lembas.param._NoDefault'>, min=None, max=None, control=False)[source]#

Bases: object

An input parameter which can be defined for a Case, which determines case-specific values.

The parameter is of a defined type and type conversion will be performed when setting the value, if appropriate.

Parameters:
  • type (type | None) – The parameter type, e.g. float, str, etc.

  • default (Any) – The default value. If the type is not set, the type of the default will be used.

  • min (float | None) – The minimum value for the parameter (if it is a float).

  • max (float | None) – The maximum value for the parameter (if it is a float).

  • control (bool) – Set as True to indicate a runtime control parameter. These parameters will be excluded from the case.inputs dictionary.

property include_in_inputs_dict: bool#

If True, include the parameter in the case.inputs dictionary.

lembas.plugins module#

exception lembas.plugins.CaseHandlerNotFound[source]#

Bases: AttributeError

lembas.plugins.load_plugins_from_file(plugin_path)[source]#

Load all defined plugins from a module from a filesystem Path.

Parameters:

plugin_path (Path) – A path to the .py file containing the Case subclasses.

Return type:

None

lembas.results module#

class lembas.results.Results(parent)[source]#

Bases: object

A generic container for results of a case.

Implements lazy loading of results, where the result accessors are specified by @result decorator.

get(item, default=None)[source]#

Dictionary-like get access.

Return type:

Any

property parent: Case#

A reference to the parent case with which these results are associated.

lembas.results.result(*func_or_names)[source]#

A decorator to annotate a method that provides result(s).

The decorator accepts a variadic list of names for the provided result(s). The method can return a single object or a tuple of objects, which must map to the number of names provided. The results are then available from within other case handler methods like self.results.result_name.

Return type:

RawCaseMethod | Callable[[RawCaseMethod], RawCaseMethod]