experimaestro 1.5.6__py3-none-any.whl → 1.5.7__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.

@@ -44,6 +44,12 @@ class LevelInformation:
44
44
  return f"[{self.level}] {self.desc} {int(self.progress*1000)/10}%"
45
45
 
46
46
 
47
+ class ListenerInformation:
48
+ def __init__(self, url: str):
49
+ self.url = url
50
+ self.error_count = 0
51
+
52
+
47
53
  class Reporter(threading.Thread):
48
54
  NOTIFICATION_FOLDER = ".notifications"
49
55
 
@@ -59,7 +65,7 @@ class Reporter(threading.Thread):
59
65
  super().__init__(daemon=True)
60
66
  self.path = path / Reporter.NOTIFICATION_FOLDER
61
67
  self.path.mkdir(exist_ok=True)
62
- self.urls: Dict[str, str] = {}
68
+ self.urls: Dict[str, ListenerInformation] = {}
63
69
 
64
70
  # Last check of notification URLs
65
71
  self.lastcheck = 0
@@ -80,7 +86,7 @@ class Reporter(threading.Thread):
80
86
  self.cv.notifyAll()
81
87
 
82
88
  @staticmethod
83
- def isfatal_httperror(e: Exception) -> bool:
89
+ def isfatal_httperror(e: Exception, info: ListenerInformation) -> bool:
84
90
  """Returns True if this HTTP error indicates that the server won't recover"""
85
91
  if isinstance(e, HTTPError):
86
92
  if e.code >= 400 and e.code < 500:
@@ -90,6 +96,13 @@ class Reporter(threading.Thread):
90
96
  return True
91
97
  if isinstance(e.reason, socket.gaierror) and e.reason.errno == -2:
92
98
  return True
99
+ if isinstance(e.reason, TimeoutError):
100
+ info.error_count += 1
101
+
102
+ # Too many errors
103
+ if info.error_count > 3:
104
+ logger.info("Too many errors with %s", info.error_count)
105
+ return True
93
106
 
94
107
  return False
95
108
 
@@ -100,8 +113,8 @@ class Reporter(threading.Thread):
100
113
  mtime = os.path.getmtime(self.path)
101
114
  if mtime > self.lastcheck:
102
115
  for f in self.path.iterdir():
103
- self.urls[f.name] = f.read_text().strip()
104
- logger.info("Added new notification URL: %s", self.urls[f.name])
116
+ self.urls[f.name] = ListenerInformation(f.read_text().strip())
117
+ logger.info("Added new notification URL: %s", self.urls[f.name].url)
105
118
  f.unlink()
106
119
 
107
120
  self.lastcheck = os.path.getmtime(self.path)
@@ -128,7 +141,9 @@ class Reporter(threading.Thread):
128
141
  params = level.report()
129
142
 
130
143
  # Go over all URLs
131
- for key, baseurl in self.urls.items():
144
+ for key, info in self.urls.items():
145
+ baseurl = info.url
146
+
132
147
  url = "{}/progress?{}".format(
133
148
  baseurl, urllib.parse.urlencode(params)
134
149
  )
@@ -147,7 +162,7 @@ class Reporter(threading.Thread):
147
162
  url,
148
163
  e,
149
164
  )
150
- if Reporter.isfatal_httperror(e):
165
+ if Reporter.isfatal_httperror(e, info):
151
166
  toremove.append(key)
152
167
 
153
168
  # Removes unvalid URLs
@@ -165,7 +180,8 @@ class Reporter(threading.Thread):
165
180
  self.check_urls()
166
181
  if self.urls:
167
182
  # Go over all URLs
168
- for key, baseurl in self.urls.items():
183
+ for key, info in self.urls.items():
184
+ baseurl = info.url
169
185
  url = "{}?status=eoj".format(baseurl)
170
186
  try:
171
187
  with urlopen(url) as _:
@@ -243,7 +259,7 @@ class xpm_tqdm(std_tqdm):
243
259
 
244
260
  def update(self, n=1):
245
261
  result = super().update(n)
246
- if self.total is not None:
262
+ if self.total is not None and self.total > 0:
247
263
  progress(self.n / self.total, level=self.pos, console=False)
248
264
  return result
249
265
 
experimaestro/run.py CHANGED
@@ -155,7 +155,6 @@ class TaskRunner:
155
155
  self.donepath.touch()
156
156
 
157
157
  # ... and finish the exit process
158
- logger.info("This is the end (TODO: remove this line)")
159
158
  raise
160
159
  else:
161
160
  self.handle_error(e.code, None)
@@ -803,11 +803,6 @@ class experiment:
803
803
  else None
804
804
  )
805
805
 
806
- # Copy environment variable from main (but do not
807
- # override)
808
- for key, value in settings.env.items():
809
- self.setenv(key, value, override=False)
810
-
811
806
  if os.environ.get("XPM_ENABLEFAULTHANDLER", "0") == "1":
812
807
  import faulthandler
813
808
 
experimaestro/settings.py CHANGED
@@ -4,6 +4,7 @@ from dataclasses import field, dataclass
4
4
  from functools import lru_cache
5
5
  from pathlib import Path
6
6
  from typing import Dict, Optional, List
7
+ import logging
7
8
 
8
9
 
9
10
  @dataclass
@@ -59,7 +60,9 @@ def get_settings(path: Optional[Path] = None) -> Settings:
59
60
 
60
61
  path = path or Path("~/.config/experimaestro/settings.yaml").expanduser()
61
62
  if not path.is_file():
62
- return schema.to_object()
63
+ return OmegaConf.to_container(
64
+ schema, structured_config_mode=SCMode.INSTANTIATE
65
+ )
63
66
 
64
67
  conf = OmegaConf.load(path)
65
68
  return OmegaConf.to_container(
@@ -78,3 +81,28 @@ def get_workspace(id: Optional[str] = None) -> Optional[WorkspaceSettings]:
78
81
  return workspace
79
82
 
80
83
  return None
84
+
85
+
86
+ def find_workspace(*, workspace: Optional[str] = None, workdir: Optional[Path] = None):
87
+ """Find workspace"""
88
+ workdir = Path(workdir) if workdir else None
89
+
90
+ if workspace:
91
+ ws_env = get_workspace(workspace)
92
+ if ws_env is None:
93
+ raise RuntimeError("No workspace named %s", workspace)
94
+
95
+ logging.info("Using workspace %s", ws_env.id)
96
+ if workdir:
97
+ # Overrides working directory
98
+ logging.info(" override working directory: %s", workdir)
99
+ ws_env.path = workdir
100
+ elif workdir:
101
+ logging.info("Using workdir %s", workdir)
102
+ ws_env = WorkspaceSettings("", workdir)
103
+ else:
104
+ ws_env = get_workspace()
105
+ assert ws_env is not None, "No workdir or workspace defined, and no default"
106
+ logging.info("Using default workspace %s", ws_env.id)
107
+
108
+ return ws_env
@@ -2,6 +2,7 @@ from typing import Dict
2
2
  from pathlib import Path
3
3
  from experimaestro import (
4
4
  tag,
5
+ LightweightTask,
5
6
  config,
6
7
  argument,
7
8
  Config,
@@ -69,6 +70,40 @@ def test_inneroutput():
69
70
  assert evaluate.__xpm__.tags() == {"hello": "world"}
70
71
 
71
72
 
73
+ def test_tags_init_tasks():
74
+ """Test tags within init tasks"""
75
+
76
+ class MyTask(Task):
77
+ pass
78
+
79
+ class InitTask(LightweightTask):
80
+ pass
81
+
82
+ class MyConfig(Config):
83
+ pass
84
+
85
+ class TaskWithOutput(Task):
86
+ x: Param[MyConfig]
87
+
88
+ def task_outputs(self, dep) -> MyConfig:
89
+ return dep(MyConfig())
90
+
91
+ init_task = InitTask().tag("hello", "world")
92
+ task = MyTask()
93
+ result = task.submit(run_mode=RunMode.DRY_RUN, init_tasks=[init_task])
94
+ assert result.tags() == {"hello": "world"}
95
+
96
+ other_task = TaskWithOutput(x=MyConfig().tag("hello", "world"))
97
+ assert other_task.tags() == {"hello": "world"}
98
+
99
+ result = other_task.submit(run_mode=RunMode.DRY_RUN)
100
+ assert isinstance(result, MyConfig)
101
+ assert result.tags() == {"hello": "world"}
102
+
103
+ result = MyTask().submit(run_mode=RunMode.DRY_RUN, init_tasks=[result])
104
+ assert result.tags() == {"hello": "world"}
105
+
106
+
72
107
  class TaskDirectoryContext(DirectoryContext):
73
108
  def __init__(self, task, path):
74
109
  super().__init__(path)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: experimaestro
3
- Version: 1.5.6
3
+ Version: 1.5.7
4
4
  Summary: "Experimaestro is a computer science experiment manager"
5
5
  Home-page: https://github.com/experimaestro/experimaestro-python
6
6
  License: GPL-3
@@ -1,7 +1,10 @@
1
1
  experimaestro/__init__.py,sha256=btjhjJa9TofgAYpMEw8SLpVH6G-5kSelxsInQdrIu30,1501
2
- experimaestro/__main__.py,sha256=iRi6yRJVcthXRTVnHQB0TNOKTRmKjdnX6yIQaf-z79o,13528
2
+ experimaestro/__main__.py,sha256=Dv9lFl03yt1dswd0Xb9NIJRgHpA5_IwH4RfQPEHyFz0,158
3
3
  experimaestro/annotations.py,sha256=dcpFmo01T12S_y5nIBIQjiXsGsq5S80ZB-58o8tW9wA,8450
4
4
  experimaestro/checkers.py,sha256=ZCMbnE_GFC5compWjt-fuHhPImi9fCPjImF8Ow9NqK8,696
5
+ experimaestro/cli/__init__.py,sha256=mzc-qqTFtZnFwCQl7IiwlYXEx08kLGwdntWayCerZ6E,9610
6
+ experimaestro/cli/filter.py,sha256=0jJrD_2cWydovjLO32vTFTK-TxXSs9P8Zxp5WaBF5AE,5790
7
+ experimaestro/cli/jobs.py,sha256=AvSrmoO8UdTDZkPxXT2iHdpcjde7CXQGs7oow0cFqY0,7319
5
8
  experimaestro/click.py,sha256=6BkeQHEgcxaxzq3xEvEEzwzuBj5-dkfrpOGikuA8L00,1377
6
9
  experimaestro/commandline.py,sha256=NS1ubme8DTJtDS2uWwdHLQiZsl6TSK1LkNxu39c3-cw,9463
7
10
  experimaestro/compat.py,sha256=dQqE2ZNHLM2wtdfp7fBRYMfC33qNehVf9J6FGRBUQhs,171
@@ -11,7 +14,7 @@ experimaestro/connectors/ssh.py,sha256=hmvU6bCq6ZsB1Zjz273mzb9pdZdTinUhUqZFJTZl8
11
14
  experimaestro/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
15
  experimaestro/core/arguments.py,sha256=dW32opqNEsULYr6nR7Zk8PqHsSCbLPclfXofw27GTpI,5620
13
16
  experimaestro/core/context.py,sha256=Q8_ngiHRBZ0laavXRJNiDvdCprrnROVTWaHfrwMdlG4,2638
14
- experimaestro/core/objects.py,sha256=s9dt7U8LDT9XNVY7mowdt1DvuBH19EO4obips1ZBSHg,63989
17
+ experimaestro/core/objects.py,sha256=vTp_zjBJlYEhe0u55erJ5X-Lc8UuTb45NIFwfVZCPes,64142
15
18
  experimaestro/core/objects.pyi,sha256=Adi2OKCW0-B9GROlEUgxxBDK6SHUqccTBHTofRRJE9M,7131
16
19
  experimaestro/core/serialization.py,sha256=9tg5ebLF3YeZ_zG9DiTHPLthppvo7io710ohD_dcLTo,3836
17
20
  experimaestro/core/serializers.py,sha256=R_CAMyjjfU1oi-eHU6VlEUixJpFayGqEPaYu7VsD9xA,1197
@@ -19,9 +22,8 @@ experimaestro/core/types.py,sha256=oTXD4UjMVoYn_Usxn2C4h6IGhYDTtekKB3O3hfeOynQ,2
19
22
  experimaestro/core/utils.py,sha256=JfC3qGUS9b6FUHc2VxIYUI9ysNpXSQ1LjOBkjfZ8n7o,495
20
23
  experimaestro/exceptions.py,sha256=cUy83WHM3GeynxmMk6QRr5xsnpqUAdAoc-m3KQVrE2o,44
21
24
  experimaestro/experiments/__init__.py,sha256=GcpDUIbCvhnv6rxFdAp4wTffCVNTv-InY6fbQAlTy-o,159
22
- experimaestro/experiments/cli.py,sha256=5G78YkzZtNU6ygcp_pRJQXYvsMWlguB9_M35-8W_Ors,7916
25
+ experimaestro/experiments/cli.py,sha256=dr-LoNNb7Nh4HCBBh4SzH5QRHXjh5tVppCjchZdZ5Hk,7254
23
26
  experimaestro/experiments/configuration.py,sha256=8GRqyLG1leF_NbvbFzqpm0yM24O0WjSNmQzvnuLnxxw,1150
24
- experimaestro/filter.py,sha256=DN1PrmS9yXoOa5Xnv001zbxzpdzvcVZFI9xZFKZ1-6g,5794
25
27
  experimaestro/generators.py,sha256=9NQ_TfDfASkArLnO4PF7s5Yoo9KWjlna2DCPzk5gJOI,1230
26
28
  experimaestro/huggingface.py,sha256=gnVlr6SZnbutYz4PLH0Q77n1TRF-uk-dR-3UFzFqAY0,2956
27
29
  experimaestro/ipc.py,sha256=ltYqybPm_XfcQC3yiskMfhfI_1dREs-XRu0F83YsNws,1490
@@ -34,7 +36,7 @@ experimaestro/launchers/__init__.py,sha256=lXn544sgJExr6uirILWzAXu_IfmfyqFZOt4Oz
34
36
  experimaestro/launchers/direct.py,sha256=VJzQNrUGnh-1Ovt6uw4yYIjXNu45QpR-_6V45lcZAfQ,1967
35
37
  experimaestro/launchers/oar.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
38
  experimaestro/launchers/slurm/__init__.py,sha256=R1Zwd4phZaXV8FwCYhzfB44n0V4cf-hBQzOc6NkFQ0s,41
37
- experimaestro/launchers/slurm/base.py,sha256=nMoSBMbA901OcneSHVXj8PXGqfv4mVN5G-NPDZ0HXO0,14135
39
+ experimaestro/launchers/slurm/base.py,sha256=syIC8Frfz-kWhpYkmPTfMjrskx7_bzvmRMQJ40lkF50,14185
38
40
  experimaestro/launchers/slurm/cli.py,sha256=c-S0TImvhZ-ZxFs5-5T2GRDm5manRYRiYudpQLHwsrQ,818
39
41
  experimaestro/launchers/slurm/configuration.py,sha256=mtozeuvIZmEfHlvEylwCgBrlVRFHT_jWNAKVxR4Tz1E,19357
40
42
  experimaestro/locking.py,sha256=hPT-LuDGZTijpbme8O0kEoB9a3WjdVzI2h31OT44UxE,1477
@@ -44,12 +46,12 @@ experimaestro/mkdocs/base.py,sha256=SwLh9s7BZfrTAZdBaealSqVeLAroDSwLLMOHmLCxMPQ,
44
46
  experimaestro/mkdocs/metaloader.py,sha256=qCqnTWhlgxql-oe46E8AbvYdoM311-lQh-msmPnbllQ,1481
45
47
  experimaestro/mkdocs/style.css,sha256=42kJ6Ozq_n4Iw5UfJ4-nO1u-HN3ELvV7Vhvj1Xkn7rQ,66
46
48
  experimaestro/mypy.py,sha256=M39VFuDrab-ymlCDIF5jys9oKpTwnuBPzb1T8Un5J3s,285
47
- experimaestro/notifications.py,sha256=936tdH_KYJYBvPVu-ii4Sn_nso_TTs5GqAfO1FDYRgc,8710
49
+ experimaestro/notifications.py,sha256=AiRFoew16Z8E0Pz9dswodOfkY5mFc5zglVPH6LqgQE4,9257
48
50
  experimaestro/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
49
51
  experimaestro/rpyc.py,sha256=ZRKol-3tVoeoUITLNFenLF4dhWBLW_FvSV_GvsypmeI,3605
50
- experimaestro/run.py,sha256=pRTj7R7N0Tzm1lAjeWyn-ewM0kNFmpU0so8Yhv0BIYs,5294
52
+ experimaestro/run.py,sha256=NTFORDb_RlEK6tWKa7K-_2_bGCdHzzjBJVH5C1ReYtw,5222
51
53
  experimaestro/scheduler/__init__.py,sha256=ERmmOxz_9mUkIuccNbzUa5Y6gVLLVDdyc4cCxbCCUbY,20
52
- experimaestro/scheduler/base.py,sha256=8fwQEBkstnBFtioJ33xD5O0iJQTNltzA2RniSTi0f-4,32120
54
+ experimaestro/scheduler/base.py,sha256=jXjep3VS5cRCjCj6vCxp4t1fGVyqQW2JQNnLp6HKmLQ,31941
53
55
  experimaestro/scheduler/dependencies.py,sha256=n9XegwrmjayOIxt3xhuTEBVEBGSq4oeVdzz-FviDGXo,1994
54
56
  experimaestro/scheduler/services.py,sha256=aCKkNZMULlceabqf-kOs_-C7KPINnjU3Q-I00o5x6iY,2189
55
57
  experimaestro/scheduler/workspace.py,sha256=vyVbYZML28zvmgxfWc2PsKKHGlrAejY43UYlttbm9AU,2280
@@ -79,7 +81,7 @@ experimaestro/server/data/index.js,sha256=f0GvRsfsQ4ayP4en7Q-raZ6buwRXLCswCbzVax
79
81
  experimaestro/server/data/index.js.map,sha256=za3MUIjzyyGRI6F5KuBFMTgrFU55xgt0LBrw-4YPHag,3904832
80
82
  experimaestro/server/data/login.html,sha256=4dvhSOn6DHp_tbmzqIKrqq2uAo0sAUbgLVD0lTnPp4s,511
81
83
  experimaestro/server/data/manifest.json,sha256=EpzHQZzrGh9c1Kf63nrqvI33H1cm0nLYfdh5lDm8ijI,318
82
- experimaestro/settings.py,sha256=Sh-OefrMEtuJJA9tRe8TiS9-BIy0b41HmHXkf1cLLzM,2181
84
+ experimaestro/settings.py,sha256=UsfKIA4Jx-32hm3xGjBs_b9uvw8M7sOYtzFyUsYSJ8s,3145
83
85
  experimaestro/sphinx/__init__.py,sha256=heovvtwbYToZM-b6HNi4pJdBoo_97usdEawhMGSK3bk,9560
84
86
  experimaestro/sphinx/static/experimaestro.css,sha256=0rEgt1LoDdD-a_R5rVfWZ19zD1gR-1L7q3f4UibIB58,294
85
87
  experimaestro/taskglobals.py,sha256=aBjPpo4HQp6E6M3GQ8L6PR4rK2Lu0kD5dS1WjnaGgDc,499
@@ -119,7 +121,7 @@ experimaestro/tests/test_progress.py,sha256=wtIGQzlV3ldd_wMng11LinVESchW-1J954mC
119
121
  experimaestro/tests/test_serializers.py,sha256=xSCezAM9yH_Ix1wr7j0au9SyBv9DtZ7b0zs2-Ynt-VM,2338
120
122
  experimaestro/tests/test_snippets.py,sha256=rojnyDjtmAMnSuDUj6Bv9XEgdP8oQf2nVc132JF8vsM,3081
121
123
  experimaestro/tests/test_ssh.py,sha256=JhwsS4lJWQeMhtnDfJhQqJ5dwEThqvcNBBgUq1EWvk0,979
122
- experimaestro/tests/test_tags.py,sha256=kanKx0TOpS7vNs5jOs-J8IuZjyUJ9zMJl2V8dfOh4Lo,1975
124
+ experimaestro/tests/test_tags.py,sha256=vfW99iFfw3m-pcJPy_-mtZsWbAt_Xw5k-u3dWoJbRWw,2921
123
125
  experimaestro/tests/test_tasks.py,sha256=bUSB_UT1MTN2P_RPHd4AT5NK-DFsgCVeFKSiXu3bEz8,9429
124
126
  experimaestro/tests/test_tokens.py,sha256=cW9qQU4PhbQY4_SgK8ICmKcYq8JVvLRTOYZzdtoS5N8,7826
125
127
  experimaestro/tests/test_types.py,sha256=2BbdB4o_2HvFkyhiQ2X3oHM49xcck-phT873NF-p8lA,1257
@@ -140,8 +142,8 @@ experimaestro/utils/resources.py,sha256=gDjkrRjo7GULWyXmNXm_u1uqzEIAoAvJydICk56n
140
142
  experimaestro/utils/settings.py,sha256=jpFMqF0DLL4_P1xGal0zVR5cOrdD8O0Y2IOYvnRgN3k,793
141
143
  experimaestro/utils/yaml.py,sha256=jEjqXqUtJ333wNUdIc0o3LGvdsTQ9AKW9a9CCd-bmGU,6766
142
144
  experimaestro/xpmutils.py,sha256=S21eMbDYsHfvmZ1HmKpq5Pz5O-1HnCLYxKbyTBbASyQ,638
143
- experimaestro-1.5.6.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
144
- experimaestro-1.5.6.dist-info/METADATA,sha256=X50UbV1oT6bEWSCm2wrLxPcIi-wO90GUC2zd8eg8JLY,6265
145
- experimaestro-1.5.6.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
146
- experimaestro-1.5.6.dist-info/entry_points.txt,sha256=PhaEili_fDgn5q7rBJGip_uhGkRBq5l3Yuhg91zkcbk,574
147
- experimaestro-1.5.6.dist-info/RECORD,,
145
+ experimaestro-1.5.7.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
146
+ experimaestro-1.5.7.dist-info/METADATA,sha256=setEZ-Qqj09KStW2IrXbenMJzVOE6eR6gPhmldyEW14,6265
147
+ experimaestro-1.5.7.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
148
+ experimaestro-1.5.7.dist-info/entry_points.txt,sha256=PhaEili_fDgn5q7rBJGip_uhGkRBq5l3Yuhg91zkcbk,574
149
+ experimaestro-1.5.7.dist-info/RECORD,,