experimaestro 2.0.0a8__py3-none-any.whl → 2.0.0b8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of experimaestro might be problematic. Click here for more details.

Files changed (122) hide show
  1. experimaestro/__init__.py +10 -11
  2. experimaestro/annotations.py +167 -206
  3. experimaestro/cli/__init__.py +278 -7
  4. experimaestro/cli/filter.py +42 -74
  5. experimaestro/cli/jobs.py +157 -106
  6. experimaestro/cli/refactor.py +249 -0
  7. experimaestro/click.py +0 -1
  8. experimaestro/commandline.py +19 -3
  9. experimaestro/connectors/__init__.py +20 -1
  10. experimaestro/connectors/local.py +12 -0
  11. experimaestro/core/arguments.py +182 -46
  12. experimaestro/core/identifier.py +107 -6
  13. experimaestro/core/objects/__init__.py +6 -0
  14. experimaestro/core/objects/config.py +542 -25
  15. experimaestro/core/objects/config_walk.py +20 -0
  16. experimaestro/core/serialization.py +91 -34
  17. experimaestro/core/subparameters.py +164 -0
  18. experimaestro/core/types.py +175 -38
  19. experimaestro/exceptions.py +26 -0
  20. experimaestro/experiments/cli.py +111 -25
  21. experimaestro/generators.py +50 -9
  22. experimaestro/huggingface.py +3 -1
  23. experimaestro/launcherfinder/parser.py +29 -0
  24. experimaestro/launchers/__init__.py +26 -1
  25. experimaestro/launchers/direct.py +12 -0
  26. experimaestro/launchers/slurm/base.py +154 -2
  27. experimaestro/mkdocs/metaloader.py +0 -1
  28. experimaestro/mypy.py +452 -7
  29. experimaestro/notifications.py +63 -13
  30. experimaestro/progress.py +0 -2
  31. experimaestro/rpyc.py +0 -1
  32. experimaestro/run.py +19 -6
  33. experimaestro/scheduler/base.py +510 -125
  34. experimaestro/scheduler/dependencies.py +43 -28
  35. experimaestro/scheduler/dynamic_outputs.py +259 -130
  36. experimaestro/scheduler/experiment.py +256 -31
  37. experimaestro/scheduler/interfaces.py +501 -0
  38. experimaestro/scheduler/jobs.py +216 -206
  39. experimaestro/scheduler/remote/__init__.py +31 -0
  40. experimaestro/scheduler/remote/client.py +874 -0
  41. experimaestro/scheduler/remote/protocol.py +467 -0
  42. experimaestro/scheduler/remote/server.py +423 -0
  43. experimaestro/scheduler/remote/sync.py +144 -0
  44. experimaestro/scheduler/services.py +323 -23
  45. experimaestro/scheduler/state_db.py +437 -0
  46. experimaestro/scheduler/state_provider.py +2766 -0
  47. experimaestro/scheduler/state_sync.py +891 -0
  48. experimaestro/scheduler/workspace.py +52 -10
  49. experimaestro/scriptbuilder.py +7 -0
  50. experimaestro/server/__init__.py +147 -57
  51. experimaestro/server/data/index.css +0 -125
  52. experimaestro/server/data/index.css.map +1 -1
  53. experimaestro/server/data/index.js +194 -58
  54. experimaestro/server/data/index.js.map +1 -1
  55. experimaestro/settings.py +44 -5
  56. experimaestro/sphinx/__init__.py +3 -3
  57. experimaestro/taskglobals.py +20 -0
  58. experimaestro/tests/conftest.py +80 -0
  59. experimaestro/tests/core/test_generics.py +2 -2
  60. experimaestro/tests/identifier_stability.json +45 -0
  61. experimaestro/tests/launchers/bin/sacct +6 -2
  62. experimaestro/tests/launchers/bin/sbatch +4 -2
  63. experimaestro/tests/launchers/test_slurm.py +80 -0
  64. experimaestro/tests/tasks/test_dynamic.py +231 -0
  65. experimaestro/tests/test_cli_jobs.py +615 -0
  66. experimaestro/tests/test_deprecated.py +630 -0
  67. experimaestro/tests/test_environment.py +200 -0
  68. experimaestro/tests/test_file_progress_integration.py +1 -1
  69. experimaestro/tests/test_forward.py +3 -3
  70. experimaestro/tests/test_identifier.py +372 -41
  71. experimaestro/tests/test_identifier_stability.py +458 -0
  72. experimaestro/tests/test_instance.py +3 -3
  73. experimaestro/tests/test_multitoken.py +442 -0
  74. experimaestro/tests/test_mypy.py +433 -0
  75. experimaestro/tests/test_objects.py +312 -5
  76. experimaestro/tests/test_outputs.py +2 -2
  77. experimaestro/tests/test_param.py +8 -12
  78. experimaestro/tests/test_partial_paths.py +231 -0
  79. experimaestro/tests/test_progress.py +0 -48
  80. experimaestro/tests/test_remote_state.py +671 -0
  81. experimaestro/tests/test_resumable_task.py +480 -0
  82. experimaestro/tests/test_serializers.py +141 -1
  83. experimaestro/tests/test_state_db.py +434 -0
  84. experimaestro/tests/test_subparameters.py +160 -0
  85. experimaestro/tests/test_tags.py +136 -0
  86. experimaestro/tests/test_tasks.py +107 -121
  87. experimaestro/tests/test_token_locking.py +252 -0
  88. experimaestro/tests/test_tokens.py +17 -13
  89. experimaestro/tests/test_types.py +123 -1
  90. experimaestro/tests/test_workspace_triggers.py +158 -0
  91. experimaestro/tests/token_reschedule.py +4 -2
  92. experimaestro/tests/utils.py +2 -2
  93. experimaestro/tokens.py +154 -57
  94. experimaestro/tools/diff.py +1 -1
  95. experimaestro/tui/__init__.py +8 -0
  96. experimaestro/tui/app.py +2395 -0
  97. experimaestro/tui/app.tcss +353 -0
  98. experimaestro/tui/log_viewer.py +228 -0
  99. experimaestro/utils/__init__.py +23 -0
  100. experimaestro/utils/environment.py +148 -0
  101. experimaestro/utils/git.py +129 -0
  102. experimaestro/utils/resources.py +1 -1
  103. experimaestro/version.py +34 -0
  104. {experimaestro-2.0.0a8.dist-info → experimaestro-2.0.0b8.dist-info}/METADATA +68 -38
  105. experimaestro-2.0.0b8.dist-info/RECORD +187 -0
  106. {experimaestro-2.0.0a8.dist-info → experimaestro-2.0.0b8.dist-info}/WHEEL +1 -1
  107. experimaestro-2.0.0b8.dist-info/entry_points.txt +16 -0
  108. experimaestro/compat.py +0 -6
  109. experimaestro/core/objects.pyi +0 -221
  110. experimaestro/server/data/0c35d18bf06992036b69.woff2 +0 -0
  111. experimaestro/server/data/219aa9140e099e6c72ed.woff2 +0 -0
  112. experimaestro/server/data/3a4004a46a653d4b2166.woff +0 -0
  113. experimaestro/server/data/3baa5b8f3469222b822d.woff +0 -0
  114. experimaestro/server/data/4d73cb90e394b34b7670.woff +0 -0
  115. experimaestro/server/data/4ef4218c522f1eb6b5b1.woff2 +0 -0
  116. experimaestro/server/data/5d681e2edae8c60630db.woff +0 -0
  117. experimaestro/server/data/6f420cf17cc0d7676fad.woff2 +0 -0
  118. experimaestro/server/data/c380809fd3677d7d6903.woff2 +0 -0
  119. experimaestro/server/data/f882956fd323fd322f31.woff +0 -0
  120. experimaestro-2.0.0a8.dist-info/RECORD +0 -166
  121. experimaestro-2.0.0a8.dist-info/entry_points.txt +0 -17
  122. {experimaestro-2.0.0a8.dist-info → experimaestro-2.0.0b8.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,148 @@
1
+ """Environment capture utilities for experiment reproducibility
2
+
3
+ This module provides functions to capture the full Python environment state
4
+ when experiments are run, including:
5
+ - Git information for editable (development) packages
6
+ - Version information for all installed Python packages
7
+ """
8
+
9
+ import sys
10
+ import logging
11
+ from pathlib import Path
12
+ from typing import Optional
13
+ from importlib.metadata import distributions
14
+
15
+ from experimaestro.utils.git import get_git_info
16
+
17
+ logger = logging.getLogger("xpm.environment")
18
+
19
+
20
+ def get_environment_info() -> dict:
21
+ """Capture complete environment information for reproducibility
22
+
23
+ Returns:
24
+ Dictionary containing:
25
+ - python_version: Python interpreter version
26
+ - packages: Dict of package_name -> version for all installed packages
27
+ - editable_packages: Dict of package_name -> {version, path, git_info}
28
+ for packages installed in editable mode
29
+ """
30
+ python_version = (
31
+ f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"
32
+ )
33
+
34
+ packages = {}
35
+ editable_packages = {}
36
+
37
+ for dist in distributions():
38
+ name = dist.metadata["Name"]
39
+ version = dist.metadata["Version"]
40
+ packages[name] = version
41
+
42
+ # Check if this is an editable install by looking for direct_url.json
43
+ # PEP 610 specifies that editable installs have a direct_url.json
44
+ # with "dir_info": {"editable": true}
45
+ direct_url_file = dist._path / "direct_url.json" # type: ignore
46
+ if direct_url_file.exists():
47
+ try:
48
+ import json
49
+
50
+ direct_url = json.loads(direct_url_file.read_text())
51
+ dir_info = direct_url.get("dir_info", {})
52
+ if dir_info.get("editable", False):
53
+ # Get the source path from the URL
54
+ url = direct_url.get("url", "")
55
+ if url.startswith("file://"):
56
+ source_path = Path(url[7:]) # Remove "file://"
57
+ git_info = get_git_info(source_path)
58
+ editable_packages[name] = {
59
+ "version": version,
60
+ "path": str(source_path),
61
+ "git": git_info,
62
+ }
63
+ except (json.JSONDecodeError, OSError) as e:
64
+ logger.debug("Error reading direct_url.json for %s: %s", name, e)
65
+
66
+ return {
67
+ "python_version": python_version,
68
+ "packages": packages,
69
+ "editable_packages": editable_packages,
70
+ }
71
+
72
+
73
+ def get_editable_packages_git_info() -> dict:
74
+ """Get git information for all editable packages
75
+
76
+ This is a lighter-weight function that only captures git info for
77
+ editable packages, without listing all installed packages.
78
+
79
+ Returns:
80
+ Dictionary mapping package_name -> {version, path, git}
81
+ for packages installed in editable mode
82
+ """
83
+ editable_packages = {}
84
+
85
+ for dist in distributions():
86
+ name = dist.metadata["Name"]
87
+ version = dist.metadata["Version"]
88
+
89
+ # Check for editable install via direct_url.json
90
+ direct_url_file = dist._path / "direct_url.json" # type: ignore
91
+ if direct_url_file.exists():
92
+ try:
93
+ import json
94
+
95
+ direct_url = json.loads(direct_url_file.read_text())
96
+ dir_info = direct_url.get("dir_info", {})
97
+ if dir_info.get("editable", False):
98
+ url = direct_url.get("url", "")
99
+ if url.startswith("file://"):
100
+ source_path = Path(url[7:])
101
+ git_info = get_git_info(source_path)
102
+ editable_packages[name] = {
103
+ "version": version,
104
+ "path": str(source_path),
105
+ "git": git_info,
106
+ }
107
+ except (json.JSONDecodeError, OSError) as e:
108
+ logger.debug("Error reading direct_url.json for %s: %s", name, e)
109
+
110
+ return editable_packages
111
+
112
+
113
+ def save_environment_info(path: Path) -> dict:
114
+ """Save environment information to a JSON file
115
+
116
+ Args:
117
+ path: Path to save the environment info JSON file
118
+
119
+ Returns:
120
+ The environment info dictionary that was saved
121
+ """
122
+ import json
123
+
124
+ env_info = get_environment_info()
125
+ path.write_text(json.dumps(env_info, indent=2))
126
+ logger.info("Saved environment info to %s", path)
127
+ return env_info
128
+
129
+
130
+ def load_environment_info(path: Path) -> Optional[dict]:
131
+ """Load environment information from a JSON file
132
+
133
+ Args:
134
+ path: Path to the environment info JSON file
135
+
136
+ Returns:
137
+ Environment info dictionary if file exists and is valid, None otherwise
138
+ """
139
+ import json
140
+
141
+ if not path.exists():
142
+ return None
143
+
144
+ try:
145
+ return json.loads(path.read_text())
146
+ except (json.JSONDecodeError, OSError) as e:
147
+ logger.warning("Error loading environment info from %s: %s", path, e)
148
+ return None
@@ -0,0 +1,129 @@
1
+ """Git utilities for tracking repository state during experiments
2
+
3
+ This module provides functions to capture git repository information
4
+ when experiments are run, enabling reproducibility by recording
5
+ which code version was used.
6
+ """
7
+
8
+ import subprocess
9
+ from pathlib import Path
10
+ from typing import Optional
11
+ import logging
12
+
13
+ logger = logging.getLogger("xpm.git")
14
+
15
+
16
+ def get_git_info(cwd: Optional[Path] = None) -> Optional[dict]:
17
+ """Get git repository information for a directory
18
+
19
+ Args:
20
+ cwd: Working directory to check (defaults to current working directory)
21
+
22
+ Returns:
23
+ Dictionary with git info if in a git repository, None otherwise.
24
+ The dictionary contains:
25
+ - commit: Full commit hash (40 characters)
26
+ - commit_short: Short commit hash (7 characters)
27
+ - branch: Current branch name (None if detached HEAD)
28
+ - dirty: True if working directory has uncommitted changes
29
+ - message: First line of commit message
30
+ - author: Author of the commit
31
+ - date: Commit date in ISO format
32
+ """
33
+ if cwd is None:
34
+ cwd = Path.cwd()
35
+
36
+ try:
37
+ # Check if this is a git repository
38
+ result = subprocess.run(
39
+ ["git", "rev-parse", "--is-inside-work-tree"],
40
+ capture_output=True,
41
+ text=True,
42
+ cwd=cwd,
43
+ check=False,
44
+ )
45
+ if result.returncode != 0:
46
+ logger.debug("Not a git repository: %s", cwd)
47
+ return None
48
+
49
+ # Get full commit hash
50
+ commit = subprocess.run(
51
+ ["git", "rev-parse", "HEAD"],
52
+ capture_output=True,
53
+ text=True,
54
+ cwd=cwd,
55
+ check=True,
56
+ ).stdout.strip()
57
+
58
+ # Get short commit hash
59
+ commit_short = subprocess.run(
60
+ ["git", "rev-parse", "--short", "HEAD"],
61
+ capture_output=True,
62
+ text=True,
63
+ cwd=cwd,
64
+ check=True,
65
+ ).stdout.strip()
66
+
67
+ # Get current branch (may be None for detached HEAD)
68
+ branch_result = subprocess.run(
69
+ ["git", "symbolic-ref", "--short", "HEAD"],
70
+ capture_output=True,
71
+ text=True,
72
+ cwd=cwd,
73
+ check=False,
74
+ )
75
+ branch = branch_result.stdout.strip() if branch_result.returncode == 0 else None
76
+
77
+ # Check if working directory is dirty
78
+ dirty_result = subprocess.run(
79
+ ["git", "status", "--porcelain"],
80
+ capture_output=True,
81
+ text=True,
82
+ cwd=cwd,
83
+ check=True,
84
+ )
85
+ dirty = bool(dirty_result.stdout.strip())
86
+
87
+ # Get commit message (first line)
88
+ message = subprocess.run(
89
+ ["git", "log", "-1", "--format=%s"],
90
+ capture_output=True,
91
+ text=True,
92
+ cwd=cwd,
93
+ check=True,
94
+ ).stdout.strip()
95
+
96
+ # Get commit author
97
+ author = subprocess.run(
98
+ ["git", "log", "-1", "--format=%an <%ae>"],
99
+ capture_output=True,
100
+ text=True,
101
+ cwd=cwd,
102
+ check=True,
103
+ ).stdout.strip()
104
+
105
+ # Get commit date in ISO format
106
+ date = subprocess.run(
107
+ ["git", "log", "-1", "--format=%aI"],
108
+ capture_output=True,
109
+ text=True,
110
+ cwd=cwd,
111
+ check=True,
112
+ ).stdout.strip()
113
+
114
+ return {
115
+ "commit": commit,
116
+ "commit_short": commit_short,
117
+ "branch": branch,
118
+ "dirty": dirty,
119
+ "message": message,
120
+ "author": author,
121
+ "date": date,
122
+ }
123
+
124
+ except FileNotFoundError:
125
+ logger.debug("Git command not found")
126
+ return None
127
+ except subprocess.CalledProcessError as e:
128
+ logger.warning("Error getting git info: %s", e)
129
+ return None
@@ -3,7 +3,7 @@ from os import PathLike
3
3
  from pathlib import Path
4
4
  from typing import Union
5
5
  from importlib import resources
6
- from experimaestro.compat import cached_property
6
+ from functools import cached_property
7
7
 
8
8
 
9
9
  class ResourcePathWrapper(PathLike):
@@ -0,0 +1,34 @@
1
+ # file generated by setuptools-scm
2
+ # don't change, don't track in version control
3
+
4
+ __all__ = [
5
+ "__version__",
6
+ "__version_tuple__",
7
+ "version",
8
+ "version_tuple",
9
+ "__commit_id__",
10
+ "commit_id",
11
+ ]
12
+
13
+ TYPE_CHECKING = False
14
+ if TYPE_CHECKING:
15
+ from typing import Tuple
16
+ from typing import Union
17
+
18
+ VERSION_TUPLE = Tuple[Union[int, str], ...]
19
+ COMMIT_ID = Union[str, None]
20
+ else:
21
+ VERSION_TUPLE = object
22
+ COMMIT_ID = object
23
+
24
+ version: str
25
+ __version__: str
26
+ __version_tuple__: VERSION_TUPLE
27
+ version_tuple: VERSION_TUPLE
28
+ commit_id: COMMIT_ID
29
+ __commit_id__: COMMIT_ID
30
+
31
+ __version__ = version = '2.0.0b8'
32
+ __version_tuple__ = version_tuple = (2, 0, 0, 'b8')
33
+
34
+ __commit_id__ = commit_id = None
@@ -1,61 +1,92 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: experimaestro
3
- Version: 2.0.0a8
4
- Summary: "Experimaestro is a computer science experiment manager"
5
- License: GPL-3
3
+ Version: 2.0.0b8
4
+ Summary: Experimaestro is a computer science experiment manager
5
+ Project-URL: Homepage, https://github.com/experimaestro/experimaestro-python
6
+ Project-URL: Documentation, https://experimaestro-python.readthedocs.io/
7
+ Project-URL: Repository, https://github.com/experimaestro/experimaestro-python
8
+ Project-URL: Bug Tracker, https://github.com/experimaestro/experimaestro-python/issues
9
+ Author-email: Benjamin Piwowarski <benjamin@piwowarski.fr>
10
+ License: GPL-3.0-or-later
6
11
  License-File: LICENSE
7
12
  Keywords: experiment manager
8
- Author: Benjamin Piwowarski
9
- Author-email: benjamin@piwowarski.fr
10
- Requires-Python: >=3.10
11
13
  Classifier: Development Status :: 4 - Beta
12
14
  Classifier: Intended Audience :: Science/Research
13
15
  Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
14
16
  Classifier: Operating System :: OS Independent
15
17
  Classifier: Programming Language :: Python
16
18
  Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
17
22
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
18
- Requires-Dist: arpeggio (>=2,<3)
19
- Requires-Dist: attrs (>=23.1.0,<24)
20
- Requires-Dist: click (>=8)
21
- Requires-Dist: decorator (>=5,<6)
22
- Requires-Dist: docstring-parser (>=0.15,<1)
23
- Requires-Dist: fasteners (>=0.19,<1)
24
- Requires-Dist: flask (>=2.3,<3)
25
- Requires-Dist: flask-socketio (>=5.3,<6)
26
- Requires-Dist: gevent (>=25)
27
- Requires-Dist: gevent-websocket (>=0.10)
28
- Requires-Dist: huggingface-hub (>0.17)
29
- Requires-Dist: humanfriendly (>=10)
30
- Requires-Dist: marshmallow (>=3.20,<4)
31
- Requires-Dist: mkdocs (>=1.5,<2)
32
- Requires-Dist: omegaconf (>=2.3,<3)
33
- Requires-Dist: psutil (>=7,<8)
34
- Requires-Dist: pyparsing (>=3.1,<4)
35
- Requires-Dist: pytools (>=2023.1.1,<2024)
36
- Requires-Dist: pyyaml (>=6.0.1,<7)
37
- Requires-Dist: requests (>=2.31,<3)
38
- Requires-Dist: rpyc (>=5,<7)
39
- Requires-Dist: sortedcontainers (>=2.4,<3)
40
- Requires-Dist: termcolor (>=2.3,<3)
41
- Requires-Dist: tqdm (>=4.66.1,<5)
42
- Requires-Dist: typing-extensions (>=4.2) ; python_version < "3.12"
43
- Requires-Dist: watchdog (>=2)
23
+ Requires-Python: >=3.10
24
+ Requires-Dist: arpeggio<3,>=2
25
+ Requires-Dist: attrs<24,>=23.1.0
26
+ Requires-Dist: click>=8
27
+ Requires-Dist: decorator<6,>=5
28
+ Requires-Dist: docstring-parser<1,>=0.15
29
+ Requires-Dist: fasteners<1,>=0.19
30
+ Requires-Dist: flask-socketio<6,>=5.3
31
+ Requires-Dist: flask<3,>=2.3
32
+ Requires-Dist: gevent-websocket>=0.10
33
+ Requires-Dist: gevent>=25
34
+ Requires-Dist: huggingface-hub>0.17
35
+ Requires-Dist: humanfriendly>=10
36
+ Requires-Dist: marshmallow<4,>=3.20
37
+ Requires-Dist: omegaconf<3,>=2.3
38
+ Requires-Dist: peewee<4,>=3.17
39
+ Requires-Dist: psutil<8,>=7
40
+ Requires-Dist: pyparsing<4,>=3.1
41
+ Requires-Dist: pyperclip<2,>=1.8
42
+ Requires-Dist: pytools<2024,>=2023.1.1
43
+ Requires-Dist: pyyaml<7,>=6.0.1
44
+ Requires-Dist: requests<3,>=2.31
45
+ Requires-Dist: rpyc<7,>=5
46
+ Requires-Dist: sortedcontainers<3,>=2.4
47
+ Requires-Dist: termcolor<3,>=2.3
48
+ Requires-Dist: textual>=6
49
+ Requires-Dist: tqdm<5,>=4.66.1
50
+ Requires-Dist: typing-extensions>=4.2; python_version < '3.12'
51
+ Requires-Dist: watchdog>=2
52
+ Provides-Extra: dev
53
+ Requires-Dist: docutils>=0.18; extra == 'dev'
54
+ Requires-Dist: mypy>=1.0; extra == 'dev'
55
+ Requires-Dist: pygments>=2.15; extra == 'dev'
56
+ Requires-Dist: pytest-timeout>=2.4.0; extra == 'dev'
57
+ Requires-Dist: pytest>=8.4.1; extra == 'dev'
58
+ Requires-Dist: textual-dev>=1.8.0; extra == 'dev'
59
+ Provides-Extra: docs
60
+ Requires-Dist: myst-parser>=2.0; extra == 'docs'
61
+ Requires-Dist: sphinx-codeautolink>=0.15; extra == 'docs'
62
+ Requires-Dist: sphinx-rtd-theme>=2.0; extra == 'docs'
63
+ Requires-Dist: sphinx>=6; extra == 'docs'
64
+ Provides-Extra: ssh
65
+ Requires-Dist: fabric>=3; extra == 'ssh'
66
+ Requires-Dist: paramiko>=3.3; extra == 'ssh'
44
67
  Description-Content-Type: text/markdown
45
68
 
46
69
  [![PyPI version](https://badge.fury.io/py/experimaestro.svg)](https://badge.fury.io/py/experimaestro)
47
70
  [![RTD](https://readthedocs.org/projects/experimaestro-python/badge/?version=latest)](https://experimaestro-python.readthedocs.io)
48
71
 
49
- Experimaestro helps in designing and managing complex workflows. It allows for the definition of tasks and their dependencies, ensuring that each step in a workflow is executed in the correct order. Some key aspects of Experimaestro are:
72
+ Experimaestro helps in designing and managing **complex experimental plans**. It allows for the definition of tasks and their dependencies, ensuring that each step in a workflow is executed in the correct order. Some key aspects of Experimaestro are:
50
73
 
51
74
  - **Task Automation**: The tool automates repetitive tasks, making it easier to run large-scale experiments. It's particularly useful in scenarios where experiments need to be repeated with different parameters or datasets.
52
75
  - **Resource Management**: It efficiently manages computational resources, which is critical when dealing with data-intensive tasks or when running multiple experiments in parallel.
53
- - **Extensibility**: Experimaestro is designed to be flexible and extensible, allowing users to integrate it with various programming languages and tools commonly used in data science and research.
54
- - **Reproducibility**: By keeping a detailed record of experiments, including parameters and environments, it aids in ensuring the reproducibility of scientific experiments, which is a fundamental requirement in research.
55
- - **User Interface**: While primarily a back-end tool, Experimaestro also offers a user interface to help in managing and visualizing workflows.
76
+ - **Reproducibility**: By keeping a detailed record of experiments (the experimental plan in python), including parameters and environments, it aids in ensuring the reproducibility of scientific experiments, which is a fundamental requirement in research.
77
+ - **User Interface**: While primarily a back-end tool, Experimaestro also offers a user interface to help in managing and visualizing workflows (web and text-based).
78
+
79
+ The full documentation can be read by going to the following URL: [https://experimaestro-python.readthedocs.io](https://experimaestro-python.readthedocs.io). A tutorial (training a CNN on MNIST) is [available on github](https://github.com/experimaestro/experimaestro-demo).
80
+
81
+ # Screenshots
56
82
 
57
- The full documentation can be read by going to the following URL: [https://experimaestro-python.readthedocs.io](https://experimaestro-python.readthedocs.io)
83
+ ## Textual interface (new in v2)
58
84
 
85
+ ![Experiment screen](docs/source/img/tui-experiments.png)
86
+
87
+ ![Jobs screen](docs/source/img/tui-jobs.png)
88
+
89
+ ![Log screen](docs/source/img/tui-logs.png)
59
90
 
60
91
  # Install
61
92
 
@@ -150,4 +181,3 @@ if __name__ == "__main__":
150
181
  ```
151
182
 
152
183
  which can be launched with `python test.py /tmp/helloworld-workdir`
153
-
@@ -0,0 +1,187 @@
1
+ experimaestro/__init__.py,sha256=X8HN3hjYVAZk2g7ogRApBbAjMtQrE-HDpEeYLtcu0CU,1720
2
+ experimaestro/__main__.py,sha256=Dv9lFl03yt1dswd0Xb9NIJRgHpA5_IwH4RfQPEHyFz0,158
3
+ experimaestro/annotations.py,sha256=1gdi17YT7t1WteJCUz7SAis0J1ctQl2ABxlUv49mXog,8842
4
+ experimaestro/checkers.py,sha256=ZCMbnE_GFC5compWjt-fuHhPImi9fCPjImF8Ow9NqK8,696
5
+ experimaestro/click.py,sha256=6FQPLtD61C65lcOYy-dOIOukXIeJEanhAUQO1ax1jHI,1311
6
+ experimaestro/commandline.py,sha256=7sID0zHdGlyUt6vBRCyfAXlgVWDSok1cE98ZexhGjB0,9689
7
+ experimaestro/exceptions.py,sha256=dVdbYwbpJokjqu-m8go5Oh6TpvSMbT2ztv1P3aV9weQ,990
8
+ experimaestro/generators.py,sha256=t26kqGDY2Q2JfwCfO1mV48cchEM2JltAUGetJ3dBGAU,2936
9
+ experimaestro/huggingface.py,sha256=G8kTgFzhCRJJfz1DcbZsPD7NprDYVajW-rTBAjg6jX4,3000
10
+ experimaestro/ipc.py,sha256=Xn3tYME83jLEB0nFak3DwEIhpL5IRZpCl3jirBF_jl4,1570
11
+ experimaestro/locking.py,sha256=hPT-LuDGZTijpbme8O0kEoB9a3WjdVzI2h31OT44UxE,1477
12
+ experimaestro/mypy.py,sha256=WyaZU01v8sSqXc7meiIY-e8cBKqKrMbK-ITlpUkIrgc,14217
13
+ experimaestro/notifications.py,sha256=fk0G0xnpv4ps35Wp-4QN2N00i5wDAacGr_A24qOu1LM,11357
14
+ experimaestro/progress.py,sha256=1766Kf5INOUKQE4HdTy90IYcu-Pxah1F3ScEa_X4uGU,14810
15
+ experimaestro/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ experimaestro/rpyc.py,sha256=0j-kZuBWvc2uZujodX7kcgz3QDJ44ZgnG7Is_bPeSDg,3591
17
+ experimaestro/run.py,sha256=N2CFTB5eVNC40tE3vjQgXPZK9WD5alwPe4Fpieo_e8E,5989
18
+ experimaestro/scriptbuilder.py,sha256=wJR20Az-YYWR0i_WLWb-VtgV3IIXYuC-LyutorfVF1I,5308
19
+ experimaestro/settings.py,sha256=ymA-W2-cNOE1W8oc7lPPxOwEz2wXSX9Q5iftw0agKcY,4489
20
+ experimaestro/taskglobals.py,sha256=A_P49RHu8FLOfoybfwcLzDcDZiUug4mLFKiAzsCof_k,1315
21
+ experimaestro/tokens.py,sha256=IitlWi8CJprTXFTw0GJ3cf-vch-x5IyJztiik5FYC1M,18578
22
+ experimaestro/typingutils.py,sha256=v7wS9xewF3cYOKvaBFxlTB-qplJ8olI1OaO3tAKiwIo,3678
23
+ experimaestro/version.py,sha256=xb387tRebssohFiC2cBfY1gEG-Ur9UZkojiYpRcNRbA,712
24
+ experimaestro/xpmutils.py,sha256=S21eMbDYsHfvmZ1HmKpq5Pz5O-1HnCLYxKbyTBbASyQ,638
25
+ experimaestro/cli/__init__.py,sha256=-ps3-5_fnqH61oRbCYZ1h-bWoLazHjLXIJP2mMYSWFY,17989
26
+ experimaestro/cli/filter.py,sha256=0Lq9B_ZNSjVU1N6sCv-YETjAPtRVwunlfGxtG6aeBpY,5024
27
+ experimaestro/cli/jobs.py,sha256=lnxlISYjVzdOk3lkEhIuV0MRyCO1JprTgg56R5KJ1No,10049
28
+ experimaestro/cli/progress.py,sha256=I6qhVe-vvqA1ym6XJE75q7Hb0jGeFwgodIqfhlTrPKY,8200
29
+ experimaestro/cli/refactor.py,sha256=qKEMi1EfN-qUGCutpH4cy5co-E1XZyLm_FLDgQaOk3M,8297
30
+ experimaestro/connectors/__init__.py,sha256=vQjUd2pDIKQr5P4sJPHsS3UfXraIizECP1sCZ9HAVmM,6768
31
+ experimaestro/connectors/local.py,sha256=gvzydQeOeaHfckIiPa6K4lADjIFkU2LsGEaqLgroxb8,6614
32
+ experimaestro/connectors/ssh.py,sha256=5giqvv1y0QQKF-GI0IFUzI_Z5H8Bj9EuL_Szpvk899Q,8600
33
+ experimaestro/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
+ experimaestro/core/arguments.py,sha256=PhhltA-j8f9bcp_be6vaKxPdXpimOARTQmYCGvIfaZI,13163
35
+ experimaestro/core/callbacks.py,sha256=59JfeUgWcCCdIQ3pvh-xNnoRp9BX8f4iOAkgm16wBzE,1660
36
+ experimaestro/core/context.py,sha256=1tLmX7WcgEKSbGw77vfziTzS8KNsoZJ02JBWMBCqqOk,2606
37
+ experimaestro/core/identifier.py,sha256=zGalnUkSLfIs7TnuVaFXEr0tgb5RLdPiXrw1WHxrhqo,15401
38
+ experimaestro/core/serialization.py,sha256=nwHqnSjplceGxFJs1CsVkHmlG6uK89G_nXq39B0FYrg,8365
39
+ experimaestro/core/serializers.py,sha256=iOBuASEgD8dRKPnL16iOLBsM0GHChCJgjBd7LixFui4,919
40
+ experimaestro/core/subparameters.py,sha256=bIF4bTkcSyjeNh_07QnfN_83fow7_tGdeeDCtnf0kb8,5833
41
+ experimaestro/core/types.py,sha256=Yd4jgO6xt0LxvJl1jZek13WMXlw3MlZumxfGxQdaVJk,26843
42
+ experimaestro/core/utils.py,sha256=JfC3qGUS9b6FUHc2VxIYUI9ysNpXSQ1LjOBkjfZ8n7o,495
43
+ experimaestro/core/objects/__init__.py,sha256=-7FUbhIgZ1_eqi9RKwQZRPmxrtLgt2DqqOge7Blz5ZU,833
44
+ experimaestro/core/objects/config.py,sha256=YXJ5_B8mmW_tVvjGGhCVQPic3iLbU1xFv6xKuXRthqs,74400
45
+ experimaestro/core/objects/config_utils.py,sha256=ZLECGkeIWdzunm8vwWsQhvcSgV1e064BgXbLiZnxSEM,1288
46
+ experimaestro/core/objects/config_walk.py,sha256=lMK7dXMjqfDaqc4NPxenYABozKYusmJ8xhDbDFP8z5U,4980
47
+ experimaestro/experiments/__init__.py,sha256=GcpDUIbCvhnv6rxFdAp4wTffCVNTv-InY6fbQAlTy-o,159
48
+ experimaestro/experiments/cli.py,sha256=WbeK4PNEy9cQoX_mJiLkMuu57lCLURg2I7dC3nECTmY,13345
49
+ experimaestro/experiments/configuration.py,sha256=vVm40BJW5sZNgSDZ0oBzX15jTO9rmOewVYrm0k9iXXY,1466
50
+ experimaestro/launcherfinder/__init__.py,sha256=qRUDyv3B9UsAM8Q31mRrZrTZox0AptwdmOY4f2K-TUo,279
51
+ experimaestro/launcherfinder/base.py,sha256=q47SsF_cXdo5O6ZhFKn5385WVFcx8Wd-BcEpd6tRpbs,515
52
+ experimaestro/launcherfinder/parser.py,sha256=2Z4lIX5drbZr5jWqL2vZy1qmPfFw_homxaXEb86fKTc,3489
53
+ experimaestro/launcherfinder/registry.py,sha256=qP2Y9mfxn7XvIBr4ot2zkyKw6sWhmgBxDDKU5Ty04FE,6417
54
+ experimaestro/launcherfinder/specs.py,sha256=eQC2pwAnvq7kF2xmAfHpg_Wx6_lH6YMf3ZCDwqatjKk,7898
55
+ experimaestro/launchers/__init__.py,sha256=asoe6Bn7tjXEpZL7sfpV5V7k7YWFexZWaxtYtBY7Se8,3440
56
+ experimaestro/launchers/direct.py,sha256=7Uec6dkssUzHOYcXz6ZwOr-NF-CuiXuQU3Uj11IHKz0,678
57
+ experimaestro/launchers/oar.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
58
+ experimaestro/launchers/slurm/__init__.py,sha256=R1Zwd4phZaXV8FwCYhzfB44n0V4cf-hBQzOc6NkFQ0s,41
59
+ experimaestro/launchers/slurm/base.py,sha256=YTL-bCH0EKCkI9LJcbXPQWpraLF5UzD3b6vRoxDGrWA,20952
60
+ experimaestro/mkdocs/__init__.py,sha256=L9UDM7vOrRZl41zXTBOaHKSINEEsbmxwjIMIGESmLfU,46
61
+ experimaestro/mkdocs/annotations.py,sha256=qpDw8lzrxpsOShXcpcP_LAeR3UhiIXAybG8UvS64-OU,263
62
+ experimaestro/mkdocs/base.py,sha256=qHDZZFdoNRsW6RcjRB1WCSp2sOtRiBk9zFO1acK05BQ,16706
63
+ experimaestro/mkdocs/metaloader.py,sha256=ItchfE3emrzKUrT-8f8WsDHNHisYzs9XDCzhWcu6VaQ,1471
64
+ experimaestro/mkdocs/style.css,sha256=42kJ6Ozq_n4Iw5UfJ4-nO1u-HN3ELvV7Vhvj1Xkn7rQ,66
65
+ experimaestro/scheduler/__init__.py,sha256=HssbogPCuGpKGMPZQP07XCT2-uMFRPANuPM-duMIrq4,422
66
+ experimaestro/scheduler/base.py,sha256=IMVwLUEm0hPJzfX0sb6efI1Ic1-o1Ya56mlxG8FXyqI,28269
67
+ experimaestro/scheduler/dependencies.py,sha256=gQfmIEa8l9mMVMmBuoPfUM30eQzEozFkCQGXkbfXhaU,2406
68
+ experimaestro/scheduler/dynamic_outputs.py,sha256=pKSm73D_XIgUHawf432JJXfQKISO34qEMf5w-nWTl-g,11187
69
+ experimaestro/scheduler/experiment.py,sha256=N7-903ADgqlJumgldOdS4BAI2nIcKPFUCDXqW_mHLsQ,22334
70
+ experimaestro/scheduler/interfaces.py,sha256=JG1Z6iGWosiM-TrEkxhsPz-dJ4lfPQL6dnaGjbCn-aA,16008
71
+ experimaestro/scheduler/jobs.py,sha256=h04Vj595zxvpgvJOr-3wK_rFBvVmlYqO68gq1euI4vc,15634
72
+ experimaestro/scheduler/services.py,sha256=CVZ7YDB71qQe86oCEQWPzgRTchEtYUZWx3KxqGykhnc,13053
73
+ experimaestro/scheduler/signal_handler.py,sha256=B4ZeSVB8O41VDdFmV4n2cyBds7wKFG3kH2Fp7cpyxa4,872
74
+ experimaestro/scheduler/state.py,sha256=1ICn1K5gNMCEUb85vwwXLIUF6Lxqa5mbTgMzEz2pnXw,2367
75
+ experimaestro/scheduler/state_db.py,sha256=HmM0PCKZoGix_VR571M4ZATag7e52KeWaFhOzBtRgRE,15855
76
+ experimaestro/scheduler/state_provider.py,sha256=X3sqdC8UnUlnveaFjMwjnEhCkHuiLpM9xp1WRpskAiE,94907
77
+ experimaestro/scheduler/state_sync.py,sha256=yrwHdGqUck_QbVCHymP5mnJHN1Z_0dILleV_vDw16KQ,34678
78
+ experimaestro/scheduler/workspace.py,sha256=hIASgxGQtrlN4oPFDqDYXTVnxDbngirGdDyAJxJq4vg,3815
79
+ experimaestro/scheduler/remote/__init__.py,sha256=QBXrl4V09nPbwxKRtV7-uLdZCXtktWBeSAV7kB2ZWOM,1134
80
+ experimaestro/scheduler/remote/client.py,sha256=FX9ZieKfz2s7SBt1KWGOLUqwuey2EAnzasKdAB8Ifsg,31501
81
+ experimaestro/scheduler/remote/protocol.py,sha256=Rc2_nsln-xw9kMnDOMbMXSIIgIjMciYhLCg4caHZgFs,13831
82
+ experimaestro/scheduler/remote/server.py,sha256=T61yaaU-tn3Pmh0wevrozyl20Oj_D5S5S-SpKGy_nQ0,15739
83
+ experimaestro/scheduler/remote/sync.py,sha256=BgPK96EJY3AxjBmrwo53CN5fUmGED-a12ZTODkJ_mQk,4917
84
+ experimaestro/server/__init__.py,sha256=BXLPcDRy7Bxx0xk24SF8OthvcE_rk7Afx7yVvgYvM2o,15920
85
+ experimaestro/sphinx/__init__.py,sha256=DhFRj8MxA9XZH-TCnbl_5bYhGiF4ihiuFwQj74oPEp4,9466
86
+ experimaestro/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
87
+ experimaestro/tests/conftest.py,sha256=9LT2rPsMUZOejUzeazL6IQRJhoM3VbhG2_oOVhZ6Hto,3757
88
+ experimaestro/tests/definitions_types.py,sha256=nMoQxZxhTJAYV87Ce9F2dAITxXGHf7Uw5j-MKsZ3LmQ,399
89
+ experimaestro/tests/identifier_stability.json,sha256=ygb6p1e8RsjGoqvGoW02ftFCCZIXAZIBsDZjP0Zsdhg,3791
90
+ experimaestro/tests/restart.py,sha256=aAizVLvw2DaNfIzuRB13iYXOoX1Q5NkgsngumERlo2s,4191
91
+ experimaestro/tests/restart_main.py,sha256=iAFzw0H1q9Aq7t6TrSAj236QBnYU52qx0VF-2dz6tx4,295
92
+ experimaestro/tests/task_tokens.py,sha256=vgqUa-S_YC2Id9pGOSv40qFTwq1WGZkFhr556Z5o678,477
93
+ experimaestro/tests/test_checkers.py,sha256=e6Rv2TlePRY__VXs0vUb6a5Aw_KIq_cs4N86VhnYHtw,407
94
+ experimaestro/tests/test_cli_jobs.py,sha256=hQimCKsgr44smvX7rxoOUS2knGBpcfvIhuwZWSSawic,19358
95
+ experimaestro/tests/test_dependencies.py,sha256=LvpmMcfnRzQPzUIuFNCIQnJot8YBSxCA827xh9gYlq0,1890
96
+ experimaestro/tests/test_deprecated.py,sha256=SWuc37o9E-9VsWnwNQBHWiWHdn4syeVTouMSPWyqhww,20061
97
+ experimaestro/tests/test_environment.py,sha256=HEIV4OIBaPdGnqi8bdqkwucc2Ezr-VMnNUiA2qYVIHE,6923
98
+ experimaestro/tests/test_experiment.py,sha256=Nfevu_aMyX4c5xTjDHMeKXZWs2HMOhy96tsQlnF-IVs,1693
99
+ experimaestro/tests/test_file_progress.py,sha256=uNUUq-ptcnxu56zRvUUZ5EYM9ZIQbUmOU_LI0roMgSw,15119
100
+ experimaestro/tests/test_file_progress_integration.py,sha256=IsRwhcNWgTRXD6pum19K0HXptxOu8Qm5zulKCZBtBPQ,16758
101
+ experimaestro/tests/test_findlauncher.py,sha256=KPy8ow--NXS1KFCIpxrmEJFRvjo-v-PwlVHVyoVKLPg,3134
102
+ experimaestro/tests/test_forward.py,sha256=UYYmFl3N4icoA024ubKmCq_vngrGK2aBthfFptIX66U,786
103
+ experimaestro/tests/test_generators.py,sha256=R0UypTzxX0dPYvY4A_kozpLDHhGzQDNfLQyc0oRaSx8,2891
104
+ experimaestro/tests/test_identifier.py,sha256=oPqCqAIXGsjkXF3-UNtltbFSHRJREUpo-hx2r4Oz5dg,26776
105
+ experimaestro/tests/test_identifier_stability.py,sha256=GgfXC-DFIKrA9uTT0-Zm3B2SkbB1llNS2Ls6o4eKvQ4,12572
106
+ experimaestro/tests/test_instance.py,sha256=CZ49fjEIvbiJCb-GdDRSt7kP48JnpZUk1GvSvXNb1Bc,1376
107
+ experimaestro/tests/test_multitoken.py,sha256=md2egK58goaHmXNP030GECvTOSG-03LqyTZDyREOKkk,14446
108
+ experimaestro/tests/test_mypy.py,sha256=wtcPd8vCn7mCyMo5-DCaOEYZS9IARw3IGa-C4ezGKxs,11900
109
+ experimaestro/tests/test_objects.py,sha256=YVOfdWjAieFTWQFqm9Q6RFg8rBgNmP8_PXXmkX_RLMA,9988
110
+ experimaestro/tests/test_outputs.py,sha256=wO53O6yWVT2sBlRXHTgsv_9i_Y8X5-JnOVfrExQSw2M,826
111
+ experimaestro/tests/test_param.py,sha256=cmCvzpCGSNpcFAI2lfIQe2lTYBfxO8gr5I0SVXiNafQ,7346
112
+ experimaestro/tests/test_partial_paths.py,sha256=XiYJsqP8IFW-gypvWBrXziMBBk3naXJp2-0OnEgKoUQ,9066
113
+ experimaestro/tests/test_progress.py,sha256=Baz2z749CWmMauldMxfMr8A77w3lRNr8eDpsPn317sc,5968
114
+ experimaestro/tests/test_remote_state.py,sha256=cILubH-dF1iFMmBYLQtVsbpmfJQgDEaK7xHKOe9edGg,23217
115
+ experimaestro/tests/test_resumable_task.py,sha256=H5plRfuQ7bhWzP9TQgGAxm6-GlbtPOTLm9WMZhvRUZ0,17080
116
+ experimaestro/tests/test_serializers.py,sha256=DWe3gbaQP16tQawDz8uSiDpQ_nyTuYjFMvoGEwIWfhU,5302
117
+ experimaestro/tests/test_snippets.py,sha256=rojnyDjtmAMnSuDUj6Bv9XEgdP8oQf2nVc132JF8vsM,3081
118
+ experimaestro/tests/test_ssh.py,sha256=KS1NWltiXrJBSStY9d4mwrexeqgNGWmhxuAU_WLQDAU,1449
119
+ experimaestro/tests/test_state_db.py,sha256=4FfMXYCJyZCltnwKf6ITX08_xXozFJxkcCmrLVlTGzQ,14197
120
+ experimaestro/tests/test_subparameters.py,sha256=mDDwPK-KlaZBf0uStxLOhxKElxhp_7mb1DYNJ02yfvg,5792
121
+ experimaestro/tests/test_tags.py,sha256=VTjowJljm8sCGiEuOIDeoNO4NPJNY1pu4b7G8dWqBes,6596
122
+ experimaestro/tests/test_tasks.py,sha256=E4LWKR_6N4bD0iONeGHQ24c4iNcXsp8l1f4jnwq0MH4,9104
123
+ experimaestro/tests/test_token_locking.py,sha256=Le8dAlQEoiDHK2_c_rMGsUlCMpjuBsLUkN4qHzz_9wk,7009
124
+ experimaestro/tests/test_tokens.py,sha256=KfpReZCC2MuxNiPPD8addl84arhN16OugrGs6tuuyPo,8075
125
+ experimaestro/tests/test_types.py,sha256=AavpWOtwQTVp5IuzfwRskBU4khoeomXXizhZoeSVPp4,4724
126
+ experimaestro/tests/test_validation.py,sha256=tinkXETcAGtgPIsmbioKSU00kGIV1YnniHTGDDcUOq8,4118
127
+ experimaestro/tests/test_workspace_triggers.py,sha256=idXnS95CBNmTj3YajWS93ZCZfVzOffne2hcMIwmEd2w,4700
128
+ experimaestro/tests/token_reschedule.py,sha256=CL3IrCyPfPRJXxC1kTbx8_QO0qUnesJd8u0gPfyCatA,1794
129
+ experimaestro/tests/utils.py,sha256=nwG1FfXsceWxnhAwG6XWL4aDCTaH5FqxYcjG74mJOks,3805
130
+ experimaestro/tests/connectors/test_local.py,sha256=hMX3maYYRABGXqRZFZbTWjf-jcvPkBq9nReLtDwLydk,1204
131
+ experimaestro/tests/connectors/utils.py,sha256=9sM3Pwy2nRfSr7pwQoOoSCDhBrEcDsEElI08Fmrw_gU,702
132
+ experimaestro/tests/connectors/bin/executable.py,sha256=RmCrH_MQiHuPRyeTP2jut0ASpfvHEH1QCxRnlvDZW2s,21
133
+ experimaestro/tests/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
134
+ experimaestro/tests/core/test_generics.py,sha256=oRKSmmofWBwnL2DgUtILSuzjgaTd7Y3EeN003Me9SQk,5214
135
+ experimaestro/tests/launchers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
136
+ experimaestro/tests/launchers/common.py,sha256=WqVcWX3g0XYJS0aJO7XWVvOmncRBbQmGvuNxH9AHUAE,2998
137
+ experimaestro/tests/launchers/test_local.py,sha256=4oGgWH2YgkEm-Muu6s4cwlgriXtYr5xAd72DVoIw_Yk,717
138
+ experimaestro/tests/launchers/test_slurm.py,sha256=IRg9B4lpbRmx5u1vkCA9FlSbqlXCyf74_VV6AAil4Xw,5968
139
+ experimaestro/tests/launchers/bin/sacct,sha256=hSrYRbwQBB0vY-Bn_FWvuU1xEXAv5G3fTUGglRpyv74,788
140
+ experimaestro/tests/launchers/bin/sbatch,sha256=iaek9dgAFeEs927QOQQcWkCIkXL-6PFsTSk4qjIx9ZQ,1780
141
+ experimaestro/tests/launchers/bin/srun,sha256=3oE3qq0UFpVtTvXfR1kH3tovFYX74fp1Fk-o8zgsaJA,47
142
+ experimaestro/tests/launchers/bin/test.py,sha256=MbxdAd2Sf7T-Hj3ldmrtngbQuBdNOkXjMcICJTf39wI,477
143
+ experimaestro/tests/launchers/config_slurm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
144
+ experimaestro/tests/launchers/config_slurm/launchers.py,sha256=DohwQVv1eXWfDpAYFg7KJekEm7q7G-lMou2lPg-PKOk,838
145
+ experimaestro/tests/scripts/notifyandwait.py,sha256=3BLXLI5XgP3BnKf6sQ56oKoMVqR80VMHmploJ3JO6Ko,407
146
+ experimaestro/tests/scripts/waitforfile.py,sha256=EDT-TuFi2fU_qt51K5EmAxjw_OnJKkBW7UCfhrtDbVw,120
147
+ experimaestro/tests/tasks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
148
+ experimaestro/tests/tasks/all.py,sha256=2KF0D1CB2PBwM_aXX09Ug6vy0MUQgoTATdheNeNKXHg,2101
149
+ experimaestro/tests/tasks/foreign.py,sha256=uhXDOcWozkcm26ybbeEU9RElJpbhjC-zdzmlSKfPcdY,122
150
+ experimaestro/tests/tasks/test_dynamic.py,sha256=NNw6IgZ8-LTmjsTU7cekb1YvQxbU4oFBj-Bbyc2Ir98,7984
151
+ experimaestro/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
152
+ experimaestro/tools/diff.py,sha256=mrI9QlZAVgMOGfyz3ryQT9wu5JBn9ndAiVk_EpCh0m4,3711
153
+ experimaestro/tools/documentation.py,sha256=O2UzjzodPqGot3YSe6NYlK7S42XpplakUdqxFpvjqHQ,9184
154
+ experimaestro/tools/jobs.py,sha256=63bXhJ7RGdczLU_nxu2skGn-9dwgr4r5pD23qH4WeBA,3516
155
+ experimaestro/tui/__init__.py,sha256=BTf7I5HtG7AA_vGTSG891Jjz4R3wf-cEnpaEwB6xBA4,197
156
+ experimaestro/tui/app.py,sha256=YXysC-VZaa-PRUUKyBaVdM_4IeC1SPSM7SFgGoLl5eI,89788
157
+ experimaestro/tui/log_viewer.py,sha256=TFybc1LsCjbaC5sUQ8WMAwP6Uzy92GknpEmYx1u0csI,6938
158
+ experimaestro/utils/__init__.py,sha256=iuBQw4lZT9Z4BIfQg0Yl9JHdbPgkSvkTH24xREeGHiI,3113
159
+ experimaestro/utils/asyncio.py,sha256=9r_vFQs6T6tqmymC_DbHVFhY9YVRO6X48uEuyL_ugP8,726
160
+ experimaestro/utils/environment.py,sha256=G_sxSsFK1sZg-nfLwNxVTUT3uq_PnEm7wio8vk0rYpk,5051
161
+ experimaestro/utils/git.py,sha256=l2jcqRIgSygg5ZtrlFE9w5hsS4gr2Zca4I5OGmAwMdo,3830
162
+ experimaestro/utils/jobs.py,sha256=42FAdKcn_v_-M6hcQZPUBr9kbDt1eVsk3a4E8Gc4eu8,2394
163
+ experimaestro/utils/jupyter.py,sha256=JcEo2yQK7x3Cr1tNl5FqGMZOICxCv9DwMvL5xsWdQPk,2183
164
+ experimaestro/utils/multiprocessing.py,sha256=am3DkHP_kmWbpynbck2c9QystCUtPBoSAC0ViBVzndU,1275
165
+ experimaestro/utils/resources.py,sha256=I0UPGMhQ_bttWt5JJLs1r-CmQsCHwtbmYjUN8JJLFKg,1317
166
+ experimaestro/utils/settings.py,sha256=jpFMqF0DLL4_P1xGal0zVR5cOrdD8O0Y2IOYvnRgN3k,793
167
+ experimaestro/server/data/1815e00441357e01619e.ttf,sha256=gIRDrmyCBDla3YVD2oqQpguTdvsPh-2OjqN9EJWW2AU,210792
168
+ experimaestro/server/data/2463b90d9a316e4e5294.woff2,sha256=qnWZhiOjkeYcaQF5Ss6DLj7N0oi1bWCPIb6gQRrMC44,158220
169
+ experimaestro/server/data/2582b0e4bcf85eceead0.ttf,sha256=0vBZNUCw4zum3iVaVPJy1GbjEUSAaVa-qM_b9-3_yb0,426112
170
+ experimaestro/server/data/89999bdf5d835c012025.woff2,sha256=40VtEoO511M3p3Pf0Ue_kI_QLAG0v0hXbYYDppsTy-U,25472
171
+ experimaestro/server/data/914997e1bdfc990d0897.ttf,sha256=VM9ghve7IfnQcq1JShm0aB-lFt0KFM7lLaAdNlGpE6M,68064
172
+ experimaestro/server/data/c210719e60948b211a12.woff2,sha256=1yNqGb8jy7ICcoDo9R3JnWxFl2ou1g3nM4KwNLGKK2g,118684
173
+ experimaestro/server/data/favicon.ico,sha256=PRD32mxgMXg0AIFmjErFs66XQ8qaJiqw_NMS-7n0i90,3870
174
+ experimaestro/server/data/index.css,sha256=ZNllclp0hcPGTwVgQrGPBGwTPBIts67w6tv_sJmqmEI,389472
175
+ experimaestro/server/data/index.css.map,sha256=Wn4xr1Z8udeDGmmPaPb8XKB9967i8n-Eio5jmATjljk,571740
176
+ experimaestro/server/data/index.html,sha256=LcXSo2QU5jcmqgmFhVWWOG_CfGyrqdm3H8jwkdRgdGU,706
177
+ experimaestro/server/data/index.js,sha256=pt168t9gDsG4cqaBryVyRABgaiUMf8xBQZGxivLqPcI,3717503
178
+ experimaestro/server/data/index.js.map,sha256=B_YbANsrKUNXMQe3JH1Jhl5ZMxo6ynVm463TnMxlo4g,3911206
179
+ experimaestro/server/data/login.html,sha256=4dvhSOn6DHp_tbmzqIKrqq2uAo0sAUbgLVD0lTnPp4s,511
180
+ experimaestro/server/data/manifest.json,sha256=EpzHQZzrGh9c1Kf63nrqvI33H1cm0nLYfdh5lDm8ijI,318
181
+ experimaestro/tui/app.tcss,sha256=KsNvixGexmGld19ztBm-Nt5IH0gbclykfYgblP38Wy4,4556
182
+ experimaestro/sphinx/static/experimaestro.css,sha256=0rEgt1LoDdD-a_R5rVfWZ19zD1gR-1L7q3f4UibIB58,294
183
+ experimaestro-2.0.0b8.dist-info/METADATA,sha256=6xzN8WQQpLaaaTIA4Ujw7Jv4Sa7GP7a-VBYqAxj1eL8,6980
184
+ experimaestro-2.0.0b8.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
185
+ experimaestro-2.0.0b8.dist-info/entry_points.txt,sha256=S6AkrX0dM7MWcV-6QN6bazCcL18QAb-uyvmhtlI5hFI,440
186
+ experimaestro-2.0.0b8.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
187
+ experimaestro-2.0.0b8.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.2.1
2
+ Generator: hatchling 1.28.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any