Metadata-Version: 2.1
Name: experimaestro
Version: 0.16.0
Summary: "Experimaestro is a computer science experiment manager"
Home-page: https://github.com/experimaestro/experimaestro-python
Author: Benjamin Piwowarski
Author-email: benjamin@piwowarski.fr
License: GPL-3
Keywords: experiment manager
Platform: any
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Provides-Extra: ssh
Provides-Extra: dev
Provides-Extra: test
License-File: LICENSE

[![PyPI version](https://badge.fury.io/py/experimaestro.svg)](https://badge.fury.io/py/experimaestro)

Experimaestro is a computer science experiment manager whose goals are:

- To decompose experiments into a set of parameterizable tasks
- Schedule tasks and handle dependencies between tasks
- Avoids to re-run the same task two times by computing unique task IDs dependending on the parameters
- Handle experimental parameters through tags

The full documentation can be read by going to the following URL: [https://experimaestro-python.readthedocs.io](https://experimaestro-python.readthedocs.io)

# Install

## With pip

You can then install the package using `pip install experimaestro`

## Develop

Checkout the git directory, then

```
pip install -e .
```

# Example

This very simple example shows how to submit two tasks that concatenate two strings.
Under the curtain,

- A directory is created for each task (in `workdir/jobs/helloworld.add/HASHID`)
  based on a unique ID computed from the parameters
- Two processes for `Say` are launched (there are no dependencies, so they will be run in parallel)
- A tag `y` is created for the main task

<!-- SNIPPET: MAIN ARGS[%WORKDIR% --port 0 --sleeptime=0.0001] -->

```python
# --- Task and types definitions

import logging
logging.basicConfig(level=logging.DEBUG)
from pathlib import Path
from experimaestro import Task, Param, experiment, progress
import click
import time
import os
from typing import List

# --- Just to be able to monitor the tasks

def slowdown(sleeptime: int, N: int):
    logging.info("Sleeping %ds after each step", sleeptime)
    for i in range(N):
        time.sleep(sleeptime)
        progress((i+1)/N)


# --- Define the tasks

class Say(Task):
    word: Param[str]
    sleeptime: Param[float]

    def execute(self):
        slowdown(self.sleeptime, len(self.word))
        print(self.word.upper(),)

class Concat(Task):
    strings: Param[List[Say]]
    sleeptime: Param[float]

    def execute(self):
        says = []
        slowdown(self.sleeptime, len(self.strings))
        for string in self.strings:
            with open(string.__xpm_stdout__) as fp:
                says.append(fp.read().strip())
        print(" ".join(says))


# --- Defines the experiment

@click.option("--port", type=int, default=12345, help="Port for monitoring")
@click.option("--sleeptime", type=float, default=2, help="Sleep time")
@click.argument("workdir", type=Path)
@click.command()
def cli(port, workdir, sleeptime):
    """Runs an experiment"""
    # Sets the working directory and the name of the xp
    with experiment(workdir, "helloworld", port=port) as xp:
        # Submit the tasks
        hello = Say(word="hello", sleeptime=sleeptime).submit()
        world = Say(word="world", sleeptime=sleeptime).submit()

        # Concat will depend on the two first tasks
        Concat(strings=[hello, world], sleeptime=sleeptime).tag("y", 1).submit()


if __name__ == "__main__":
    cli()
```

which can be launched with `python test.py /tmp/helloworld-workdir`

## 0.15.1 (2023-02-08)

### Fix

- wrong indent

## 0.15.0 (2023-02-08)

### Feat

- **scheduler**: foundations for experiment services

## 0.14.6 (2023-02-06)

## 0.14.5 (2023-02-06)

## 0.14.4 (2023-02-03)

## 0.14.3 (2023-01-24)

## 0.14.2 (2023-01-21)

## 0.14.1 (2023-01-21)

## 0.14 (2023-01-19)

## 0.13.3 (2022-12-24)

## 0.13.2 (2022-12-24)

## 0.13.1 (2022-12-01)

## 0.13.0 (2022-12-01)

## 0.12.2 (2022-11-30)

## 0.12.0 (2022-11-29)

## 0.11.8 (2022-11-22)

## 0.11.7 (2022-10-24)

## 0.11.6 (2022-10-14)

## 0.11.5 (2022-10-08)

## 0.11.3 (2022-10-06)

## 0.11.2 (2022-10-05)

## 0.11.1 (2022-10-05)

## 0.10.6 (2022-09-29)

## 0.10.5 (2022-05-31)

## 0.10.4 (2022-05-12)

## 0.10.3 (2022-02-10)

## 0.10.2 (2022-02-07)

## 0.10.1 (2022-02-04)

## 0.10.0 (2022-02-04)

## 0.9.12 (2022-01-11)

## 0.9.11 (2021-11-19)

## 0.9.10 (2021-09-23)

## 0.9.9 (2021-07-22)

## 0.9.8 (2021-07-22)

## 0.9.7 (2021-07-19)

## 0.9.6 (2021-07-19)

## 0.9.5 (2021-07-19)

## 0.9.4 (2021-05-26)

## 0.9.3 (2021-05-26)

## 0.9.2 (2021-05-25)

## 0.9.1 (2021-05-24)

## 0.9.0 (2021-05-24)

## 0.8.9 (2021-05-20)

## 0.8.8 (2021-04-05)

## 0.8.7 (2021-04-03)

## 0.8.6 (2021-03-18)

## 0.8.5 (2021-03-18)

## 0.8.4 (2021-03-02)

## 0.8.3 (2021-02-19)

## 0.8.2 (2021-01-29)

## 0.8.1 (2021-01-28)

## 0.8.0 (2021-01-27)

## 0.7.12 (2021-01-12)

## 0.7.11 (2021-01-07)

## 0.7.10 (2021-01-07)

## 0.7.9 (2020-12-15)

## 0.7.8 (2020-12-09)

## 0.7.7 (2020-10-19)

## 0.7.6 (2020-10-02)

## 0.7.5 (2020-09-17)

## 0.7.4 (2020-09-11)

## 0.7.3 (2020-07-07)

## 0.7.2 (2020-05-27)

## 0.7.0 (2020-05-26)

## 0.6.0 (2020-05-21)

## 0.5.9 (2020-01-14)

## 0.5.7 (2020-01-13)

## 0.5.6 (2020-01-10)

## 0.5.5 (2019-12-19)

## 0.5.4 (2019-12-12)

## 0.5.3 (2019-12-12)

## 0.5.2 (2019-12-12)

## 0.5.1 (2019-12-11)

## 0.5.0 (2019-12-11)

## v0.3.1 (2019-02-22)

## v0.3.0 (2019-02-22)
