Extensions (erlab.extensions)¶
Simple analysis and loader extensions for ERLab.
Extension authors normally need only routine() or loader(). Decorated
functions remain ordinary Python functions and work directly in notebooks.
- exception erlab.extensions.ExtensionError[source]¶
Bases:
RuntimeErrorBase class for errors raised by the ERLab extension API.
Catch this error when one handler must process import, validation, lookup, and execution failures in the same way.
- exception erlab.extensions.ExtensionExecutionError[source]¶
Bases:
ExtensionErrorAn extension call failed or returned an unsupported value.
- exception erlab.extensions.ExtensionImportError[source]¶
Bases:
ExtensionErrorAn extension source could not be read, verified, or imported.
- exception erlab.extensions.ExtensionNotFoundError[source]¶
Bases:
ExtensionErrorA requested extension source or capability is not available.
- exception erlab.extensions.ExtensionSignatureError[source]¶
Bases:
ExtensionErrorA decorated function has an unsupported signature or annotation.
- class erlab.extensions.LoadedScript(erlab)[source]¶
Bases:
objectImported extension script with natural access to its public functions.
Instances are returned by
erlab.extensions.load_script(). Call a decorated function as a normal attribute. Useerlabonly when you need descriptors, the source hash, or other import information.- Parameters:
erlab (
LoadedScriptInfo) – ERLab information for the imported script.
Examples
>>> from erlab.extensions import load_script >>> extension = load_script("my_extension.py") >>> result = extension.normalize(data) >>> tuple(extension.erlab.routines) ('normalize',)
- property erlab: LoadedScriptInfo¶
Return descriptors and import information owned by ERLab.
- class erlab.extensions.LoadedScriptInfo(*, path, source_hash, module, routines, loaders)[source]¶
Bases:
objectERLab information for one loaded extension script.
Access this object through
LoadedScript.erlab. Keeping ERLab-owned attributes in one namespace lets extension functions use ordinary names such aspath,module, orloaders.- Parameters:
path (
Path) – Resolved source path.source_hash (
str) – SHA-256 digest of the imported source bytes.module (
Any) – Imported Python module.routines (
dict[str,tuple[RoutineDescriptor,Callable[...,Any]]]) – Routine descriptors and functions, keyed by capability ID.loaders (
dict[str,tuple[LoaderDescriptor,Callable[...,Any]]]) – Loader descriptors and functions, keyed by capability ID.
- property capabilities: tuple[RoutineDescriptor | LoaderDescriptor, ...]¶
Return all validated capabilities in source definition order.
- Returns:
tupleofRoutineDescriptororLoaderDescriptor– The routines followed by the loaders from the imported script.
- class erlab.extensions.LoaderDescriptor(**data)[source]¶
Bases:
BaseModelPublic description of a path-based data loader.
- Parameters:
id (str) – Stable capability identifier.
name (str) – Display name.
category (str) – Display category.
summary (str) – Short description.
function_name (str) – Python function name in the source module.
parameters (tuple[ParameterDescriptor, ...]) – Parameters shown after the input path.
extensions (tuple[str, ...]) – Optional filename extensions, including the leading dot.
extension_api_version (Literal[1]) – Extension protocol version used by this descriptor.
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'frozen': True}¶
Configuration for the model, should be a dictionary conforming to [
ConfigDict][pydantic.config.ConfigDict].
- id: str¶
- name: str¶
- category: str¶
- summary: str¶
- function_name: str¶
- parameters: tuple[ParameterDescriptor, ...]¶
- extensions: tuple[str, ...]¶
- extension_api_version: typing.Literal[1]¶
- class erlab.extensions.ParameterDescriptor(**data)[source]¶
Bases:
BaseModelDescription of one user-editable extension parameter.
- Parameters:
id (str) – Python parameter name.
kind (ParameterKind) – Editor type used by graphical clients.
required (bool) – Whether the caller must supply a value.
optional (bool) – Whether
Noneis an accepted value.default (bool | int | float | str | None) – JSON-compatible default value, if one exists.
choices (tuple[bool | int | float | str, ...]) – Accepted values for a literal or enumeration parameter.
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'frozen': True}¶
Configuration for the model, should be a dictionary conforming to [
ConfigDict][pydantic.config.ConfigDict].
- id: str¶
- kind: ParameterKind¶
- required: bool¶
- optional: bool¶
- default: bool | int | float | str | None¶
- choices: tuple[bool | int | float | str, ...]¶
- class erlab.extensions.ParameterKind(*values)[source]¶
Bases:
StrEnumSupported editor type for an extension parameter.
- Variables:
BOOLEAN – A Boolean value.
INTEGER – An integer value.
NUMBER – A floating-point value.
STRING – A text value.
PATH – A file-system path.
LITERAL – One value from a
Literalannotation.ENUM – One value from an enumeration.
- BOOLEAN = 'boolean'¶
- INTEGER = 'integer'¶
- NUMBER = 'number'¶
- STRING = 'string'¶
- PATH = 'path'¶
- LITERAL = 'literal'¶
- ENUM = 'enum'¶
- class erlab.extensions.RoutineDescriptor(**data)[source]¶
Bases:
BaseModelPublic description of a single-input analysis routine.
- Parameters:
id (str) – Stable capability identifier.
name (str) – Display name.
category (str) – Display category.
summary (str) – Short user-facing description.
function_name (str) – Python function name in the source module.
parameters (tuple[ParameterDescriptor, ...]) – Parameters shown after the input array.
extension_api_version (Literal[1]) – Extension protocol version used by this descriptor.
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'frozen': True}¶
Configuration for the model, should be a dictionary conforming to [
ConfigDict][pydantic.config.ConfigDict].
- id: str¶
- name: str¶
- category: str¶
- summary: str¶
- function_name: str¶
- parameters: tuple[ParameterDescriptor, ...]¶
- extension_api_version: typing.Literal[1]¶
- erlab.extensions.load_script(path, *, module_name=None, expected_source_hash=None)[source]¶
Import and validate all decorated capabilities in a Python script.
The source directory is not added to
sys.path. Each call uses a new module name unlessmodule_nameis supplied.- Parameters:
- Returns:
LoadedScript– Imported module, source hash, and validated capabilities.- Raises:
ExtensionImportError – If the source cannot be read or imported, or if
module_nameis already in use.ExtensionSignatureError – If a decorated function has an unsupported signature.
- Return type:
Examples
A script can contain routines, loaders, or both.
>>> from erlab.extensions import load_script >>> loaded = load_script("my_lab_extension.py") >>> tuple(loaded.erlab.routines) ('normalize',)
- erlab.extensions.loader(*, name=None, id=None, category='Other', summary='', extensions=())[source]¶
Mark a normal Python function as an external data loader.
The first parameter must accept
pathlib.Path. The result must be an xarrayDataArray,Dataset, orDataTree.- Parameters:
name (
str|None, default:None) – Display name. The function name is used by default.id (
str|None, default:None) – Stable capability identifier.category (
str, default:'Other') – Group shown in graphical clients.summary (
str, default:'') – Short user-facing description.extensions (
str|Iterable[str], default:()) – One filename extension or an iterable of extensions accepted by the loader. The leading dot is optional.
- Returns:
callable– A decorator that returns the supplied function unchanged.- Return type:
Examples
>>> from pathlib import Path >>> import xarray as xr >>> from erlab.extensions import loader >>> @loader(name="Text values", extensions=(".txt",)) ... def load_text(path: Path) -> xr.DataArray: ... return xr.DataArray([float(path.read_text())])
- erlab.extensions.routine(*, name=None, id=None, category='Other', summary='')[source]¶
Mark a normal Python function as an ImageTool analysis routine.
The decorator does not wrap the function. Calling the decorated function in a notebook has the same behavior as calling the original function.
- Parameters:
name (
str|None, default:None) – Display name. The function name is used by default.id (
str|None, default:None) – Stable capability identifier. Set this value before renaming a function.category (
str, default:'Other') – Group shown in graphical clients.summary (
str, default:'') – Short user-facing description.
- Returns:
callable– A decorator that returns the supplied function unchanged.- Return type:
Callable[[Callable[[…], DataArray]], Callable[[…], DataArray]]
Examples
>>> import xarray as xr >>> from erlab.extensions import routine >>> @routine(name="Double") ... def double(data: xr.DataArray) -> xr.DataArray: ... return 2 * data >>> double(xr.DataArray([1, 2])).values.tolist() [2, 4]
- erlab.extensions.run_loader(path, *, loader_id, script=None, registered_script=None, source_hash=None, parameters=None)[source]¶
Run one decorated loader without manager or Qt knowledge.
- Parameters:
loader_id (
str) – Capability identifier.script (
PathLike[str] |str|None, default:None) – Direct Python source path.registered_script (
str|None, default:None) – Registered Python script filename.source_hash (
str|None, default:None) – Required source SHA-256 hash for catalog-based replay. You can also use it to verify a direct script.parameters (
Mapping[str,Any] |None, default:None) – Loader parameter values.
- Returns:
xarray.DataArray,xarray.Dataset, orxarray.DataTree– Validated loader output.- Raises:
ExtensionNotFoundError – If the requested script, source, or loader is unavailable.
ExtensionImportError – If the script cannot be imported.
ExtensionSignatureError – If the script contains an unsupported decorated function.
ExtensionExecutionError – If the loader fails or does not return an xarray object.
- Return type:
Examples
>>> from erlab.extensions import run_loader >>> data = run_loader( ... "scan.txt", ... script="my_lab_extension.py", ... loader_id="load_scan", ... )
- erlab.extensions.run_routine(data, *, routine_id, script=None, registered_script=None, source_hash=None, parameters=None)[source]¶
Run one decorated routine without manager or Qt knowledge.
Supply
scriptfor a direct notebook call. Manager replay can instead supplyregistered_scriptandsource_hashso the active catalog resolves the recorded source.- Parameters:
data (
DataArray) – Input array.routine_id (
str) – Capability identifier.script (
PathLike[str] |str|None, default:None) – Python source file. This is optional when a manager catalog resolver exists.registered_script (
str|None, default:None) – Registered Python script filename.source_hash (
str|None, default:None) – Required source SHA-256 hash for catalog-based replay. You can also use it to verify a direct script.parameters (
Mapping[str,Any] |None, default:None) – User parameter values.
- Returns:
xarray.DataArray– Validated routine result.- Raises:
ExtensionNotFoundError – If the requested script, source, or routine is unavailable.
ExtensionImportError – If the script cannot be imported.
ExtensionSignatureError – If the script contains an unsupported decorated function.
ExtensionExecutionError – If the routine fails or does not return a
DataArray.
- Return type:
Examples
>>> import xarray as xr >>> from erlab.extensions import run_routine >>> data = xr.DataArray([1.0, 2.0]) >>> result = run_routine( ... data, ... script="my_lab_extension.py", ... routine_id="normalize", ... )