Metadata-Version: 2.4
Name: myexp
Version: 0.2.0
Summary: Python experiment script protocol helpers for Research Lab runtime tasks.
Author-email: Cai Jianping <jpingcai@163.com>
License-Expression: MIT
Project-URL: Homepage, https://pypi.org/project/myexp/
Keywords: experiments,research,runtime,protocol
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: PyYAML>=6.0

# myexp

`myexp` is the maintained Python protocol package for repository experiment scripts.
Version `0.2.0` keeps the runtime contract from `0.1.0` while making the public API smaller and better diagnosed.

## Runtime Model

One script supports both local debug and distributed runtime execution:

- local debug mode uses defaults embedded in the script;
- runtime mode uses the JSON object passed as the first command-line argument;
- runtime JSON is authoritative and never merged under local defaults.

Use `myexp.params(local_defaults)` to load parameters. If runtime JSON is present it is returned. If no runtime JSON is present, a deep copy of `local_defaults` is returned. Invalid JSON and non-object JSON raise `ParameterError` with phase, source, path, and recovery guidance.

## Preferred API

New scripts should import only `myexp` and prefer these names:

- `myexp.params(local_defaults)` and `myexp.in_runtime()`
- `myexp.emit(result)`
- `myexp.run_experiment(func, local_defaults=...)`
- `myexp.ExperimentTemplate` for YAML-backed lifecycle scripts
- `myexp.config_name(__file__)`
- `myexp.load_config(...)`, `myexp.nest_params(...)`, `myexp.unpack_params(...)`
- `myexp.filter_kwargs(func, args)`

Compatibility names remain available for existing scripts:

- `ExpTemplate`, `getParams`, `printResult`, `isExpEnv`
- `getYamlConfName`, `parseFuncParams`, `unpackAggrParam`
- `convParam2Setting`, `loadSettingFromYaml`, `removeNoneSetting`

## Minimal Script

```python
import myexp

LOCAL_DEFAULTS = {"pid": 0, "metric": 1}


def main(param):
    return {"metric": int(param["metric"]) + 1, "params": param}


if __name__ == "__main__":
    myexp.run_experiment(main, local_defaults=LOCAL_DEFAULTS)
```

## Lifecycle Script

Use `ExperimentTemplate` when the script needs `bgConfig.yaml`, a task config file, option/reference parsing, `pid` document selection, execution gating, or parameter normalization.

```python
import myexp


class Experiment(myexp.ExperimentTemplate):
    def normalize_params(self, param):
        param["metric"] = int(param["metric"]) + 1
        return param

    def execute(self, config):
        return {"metric": config["metric"], "params": config}


if __name__ == "__main__":
    Experiment(
        workSpaceDir=".",
        taskConfigName=myexp.config_name(__file__),
        local_defaults={"pid": 0, "metric": 1},
    ).run()
```

## Config Behavior

Config loading is deterministic:

1. load the selected background YAML document;
2. merge the selected task YAML document;
3. merge parameter overrides after converting `a__b` to `a.b`;
4. parse option blocks using `$` selectors with exact match, one regex match, or `default`;
5. resolve `?path.to.key` references;
6. raise `ConfigError` for missing config files, missing reference paths, ambiguous options, cycles, unsupported YAML document shapes, or invalid `pid`/document indices.

Results are sidecar-first. When `RESEARCH_LAB_RESULT_JSON` is set, `myexp.emit()` writes JSON there. Otherwise it emits the legacy stdout markers `==>**ResultJson**<==` and `==>**End**<==`.
