anemoi-utils 0.4.32__py3-none-any.whl → 0.4.34__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 anemoi-utils might be problematic. Click here for more details.

anemoi/utils/__init__.py CHANGED
@@ -9,6 +9,8 @@
9
9
 
10
10
  """Anemoi Utils package."""
11
11
 
12
+ from ._environment import ENV
13
+
12
14
  try:
13
15
  # NOTE: the `_version.py` file must not be present in the git repository
14
16
  # as it is generated by setuptools at install time
@@ -16,3 +18,8 @@ try:
16
18
  except ImportError: # pragma: no cover
17
19
  # Local copy or not installed with setuptools
18
20
  __version__ = "999"
21
+
22
+ __all__ = [
23
+ "ENV",
24
+ "__version__",
25
+ ]
@@ -0,0 +1,37 @@
1
+ # (C) Copyright 2025- Anemoi contributors.
2
+ #
3
+ # This software is licensed under the terms of the Apache Licence Version 2.0
4
+ # which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
5
+ #
6
+ # In applying this licence, ECMWF does not waive the privileges and immunities
7
+ # granted to it by virtue of its status as an intergovernmental organisation
8
+ # nor does it submit to any jurisdiction.
9
+
10
+ import os
11
+ from typing import Any
12
+
13
+
14
+ class Environment:
15
+ """Environment variables for Anemoi."""
16
+
17
+ ANEMOI_CONFIG_OVERRIDE_PATH: str
18
+ """Path to the configuration override file for Anemoi."""
19
+
20
+ def __setattr__(self, name: str, value: Any) -> None:
21
+ raise AttributeError("Cannot set attributes on Environment class. Use environment variables instead.")
22
+
23
+ def __getattr__(self, name: str) -> str | None:
24
+ if name in self.__class__.__annotations__:
25
+ if (env_var := os.getenv(name)) is None:
26
+ return env_var
27
+ try:
28
+ return self.__class__.__annotations__[name](env_var) # Auto cast
29
+ except Exception as e:
30
+ e.add_note(
31
+ f"Environment variable {name!r} must be of type {self.__class__.__annotations__[name].__name__}"
32
+ )
33
+ raise e
34
+ raise AttributeError(f"{name} is not a valid environment variable for {self.__class__.__name__}")
35
+
36
+
37
+ ENV = Environment()
anemoi/utils/_version.py CHANGED
@@ -1,7 +1,14 @@
1
1
  # file generated by setuptools-scm
2
2
  # don't change, don't track in version control
3
3
 
4
- __all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
4
+ __all__ = [
5
+ "__version__",
6
+ "__version_tuple__",
7
+ "version",
8
+ "version_tuple",
9
+ "__commit_id__",
10
+ "commit_id",
11
+ ]
5
12
 
6
13
  TYPE_CHECKING = False
7
14
  if TYPE_CHECKING:
@@ -9,13 +16,19 @@ if TYPE_CHECKING:
9
16
  from typing import Union
10
17
 
11
18
  VERSION_TUPLE = Tuple[Union[int, str], ...]
19
+ COMMIT_ID = Union[str, None]
12
20
  else:
13
21
  VERSION_TUPLE = object
22
+ COMMIT_ID = object
14
23
 
15
24
  version: str
16
25
  __version__: str
17
26
  __version_tuple__: VERSION_TUPLE
18
27
  version_tuple: VERSION_TUPLE
28
+ commit_id: COMMIT_ID
29
+ __commit_id__: COMMIT_ID
19
30
 
20
- __version__ = version = '0.4.32'
21
- __version_tuple__ = version_tuple = (0, 4, 32)
31
+ __version__ = version = '0.4.34'
32
+ __version_tuple__ = version_tuple = (0, 4, 34)
33
+
34
+ __commit_id__ = commit_id = None
anemoi/utils/config.py CHANGED
@@ -20,6 +20,8 @@ from typing import Any
20
20
 
21
21
  import yaml
22
22
 
23
+ from anemoi.utils import ENV
24
+
23
25
  try:
24
26
  import tomllib # Only available since 3.11
25
27
  except ImportError:
@@ -61,7 +63,7 @@ class DotDict(dict):
61
63
  super().__init__(*args, **kwargs)
62
64
 
63
65
  for k, v in self.items():
64
- self[k] = self.convert_to_nested_dot_dict(v)
66
+ super().__setitem__(k, self.convert_to_nested_dot_dict(v))
65
67
 
66
68
  @staticmethod
67
69
  def convert_to_nested_dot_dict(value):
@@ -204,7 +206,7 @@ class DotDict(dict):
204
206
  super().__setitem__(key, value)
205
207
 
206
208
  def warn_on_mutation(self, key):
207
- warnings.warn("Mofifying and instance of DotDict(). This class is intended to be immutable.")
209
+ warnings.warn("Modifying an instance of DotDict(). This class is intended to be immutable.")
208
210
 
209
211
  def __repr__(self) -> str:
210
212
  """Return a string representation of the DotDict.
@@ -576,6 +578,9 @@ def load_config(
576
578
 
577
579
  with CONFIG_LOCK:
578
580
  config = _load_config(name, secrets, defaults)
581
+ if ENV.ANEMOI_CONFIG_OVERRIDE_PATH is not None:
582
+ override_config = _load_config(os.path.abspath(ENV.ANEMOI_CONFIG_OVERRIDE_PATH))
583
+ merge_configs(config, override_config)
579
584
  if CONFIG_PATCH is not None:
580
585
  config = CONFIG_PATCH(config)
581
586
  return config
anemoi/utils/testing.py CHANGED
@@ -240,17 +240,6 @@ def _missing_packages(*names: str) -> list[str]:
240
240
  return missing
241
241
 
242
242
 
243
- def _run_slow_tests() -> bool:
244
- """Check if the SLOW_TESTS environment variable is set.
245
-
246
- Returns
247
- -------
248
- bool
249
- True if the SLOW_TESTS environment variable is set, False otherwise.
250
- """
251
- return bool(int(os.environ.get("SLOW_TESTS", 0)))
252
-
253
-
254
243
  @lru_cache(maxsize=None)
255
244
  def _offline() -> bool:
256
245
  """Check if we are offline."""
@@ -265,7 +254,6 @@ def _offline() -> bool:
265
254
 
266
255
 
267
256
  skip_if_offline = pytest.mark.skipif(_offline(), reason="No internet connection")
268
- skip_slow_tests = pytest.mark.skipif(not _run_slow_tests(), reason="Skipping slow tests")
269
257
 
270
258
 
271
259
  def skip_missing_packages(*names: str) -> pytest.MarkDecorator:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: anemoi-utils
3
- Version: 0.4.32
3
+ Version: 0.4.34
4
4
  Summary: A package to hold various functions to support training of ML models on ECMWF data.
5
5
  Author-email: "European Centre for Medium-Range Weather Forecasts (ECMWF)" <software.support@ecmwf.int>
6
6
  License: Apache License
@@ -1,11 +1,12 @@
1
- anemoi/utils/__init__.py,sha256=uVhpF-VjIl_4mMywOVtgTutgsdIsqz-xdkwxeMhzuag,730
1
+ anemoi/utils/__init__.py,sha256=G1BlBl5IGz1AKHYkEUNT5x69WOTV0ALEe8appAdYr38,806
2
2
  anemoi/utils/__main__.py,sha256=6LlE4MYrPvqqrykxXh7XMi50UZteUY59NeM8P9Zs2dU,910
3
- anemoi/utils/_version.py,sha256=oAm79fUiHcXTCTEkFD4DV2bxk8dDUofRGFcRzCcXEdU,513
3
+ anemoi/utils/_environment.py,sha256=sdi0h0uBMU4hhjhTi3ZitLZtrV7sRs_8KqfVeakJFWY,1400
4
+ anemoi/utils/_version.py,sha256=jwG9gRi6TMtEmZUeRVNXtD3h05Le4QjrfaURHP8y67g,706
4
5
  anemoi/utils/caching.py,sha256=wKkpsACniNCFK1nc5Tw18EAv9FJGYdhs5p8qsr8i_FI,6153
5
6
  anemoi/utils/checkpoints.py,sha256=U197rvPUD1_XBA-VphgA0staFkgx2TzDoBdbnch-I7Y,9550
6
7
  anemoi/utils/cli.py,sha256=p4sup42X7JW47AKM3IQn4_0-KUAlc5ceBMj8FYmSdlc,6500
7
8
  anemoi/utils/compatibility.py,sha256=Yx4Yj3xL5q0PxYccM3N5qGeQxTtEPfaCz4EqjrS7CUc,2175
8
- anemoi/utils/config.py,sha256=OsRWUNIezIbHpT91ESB53SzNmXURpDNYXhY8q74S_Ww,17911
9
+ anemoi/utils/config.py,sha256=ttzyq8L4dYYdqMwAD8XE7rzMXXpiA7QOWPuD1Xkq1_s,18154
9
10
  anemoi/utils/dates.py,sha256=35KyiyFW8SeWLIm7VeMKBJvNvl2nVu-edRWLX-04uT4,17307
10
11
  anemoi/utils/devtools.py,sha256=W3OBu96MkXRIl7Qh1SE5Zd6aB1R0QlnmlrlpBYM0fVY,3527
11
12
  anemoi/utils/grib.py,sha256=eHz3BVoSB4O-3RARxXFcKRSWtYVbt6lqoLBcssHOp70,3543
@@ -19,7 +20,7 @@ anemoi/utils/rules.py,sha256=YtJcwkyBJwPjHlM4ZM6icGJXLCRZmcuHCXc-SSR8wgw,6856
19
20
  anemoi/utils/s3.py,sha256=bBVlfg3R4sJYOfgrSkhX7MxSVUQEur4LjE86ug8vkNw,4052
20
21
  anemoi/utils/sanitise.py,sha256=XkQzibDbu-VFJkJC4WcB9ovkcTkVAynXtkn1Tlc2CC4,4019
21
22
  anemoi/utils/sanitize.py,sha256=43ZKDcfVpeXSsJ9TFEc9aZnD6oe2cUh151XnDspM98M,462
22
- anemoi/utils/testing.py,sha256=MKKX43mDwLhEeuMaTt05TFvXvSq6j8yW5jWENKoSiBY,11145
23
+ anemoi/utils/testing.py,sha256=u6VyarS9li5X_kqZr6hrqvwEAVjtgY9ZYdIyIsv7kyQ,10789
23
24
  anemoi/utils/text.py,sha256=9M7VepzZLL-jGfFGXDqNxjwpNl7tiU8arkkOqhT9iSE,14361
24
25
  anemoi/utils/timer.py,sha256=_leKMYza2faM7JKlGE7LCNy13rbdPnwaCF7PSrI_NmI,3895
25
26
  anemoi/utils/commands/__init__.py,sha256=5u_6EwdqYczIAgJfCwRSyQAYFEqh2ZuHHT57g9g7sdI,808
@@ -39,9 +40,9 @@ anemoi/utils/remote/s3.py,sha256=BWI4bUmZHBvvqU6idewyg4ApxTlhCtX3cpwjeheCSo4,213
39
40
  anemoi/utils/remote/ssh.py,sha256=xNtsawh8okytCKRehkRCVExbHZj-CRUQNormEHglfuw,8088
40
41
  anemoi/utils/schemas/__init__.py,sha256=nkinKlsPLPXEjfTYQT1mpKC4cvs-14w_zBkDRxakwxw,698
41
42
  anemoi/utils/schemas/errors.py,sha256=lgOXzVTYzAE0qWQf3OZ42vCWixv8lilSqLLhzARBmvI,1831
42
- anemoi_utils-0.4.32.dist-info/licenses/LICENSE,sha256=8HznKF1Vi2IvfLsKNE5A2iVyiri3pRjRPvPC9kxs6qk,11354
43
- anemoi_utils-0.4.32.dist-info/METADATA,sha256=WyYYg-sVWEvRSZH9-uyqAdP3oemUq4DI97sZExxibD8,15668
44
- anemoi_utils-0.4.32.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
45
- anemoi_utils-0.4.32.dist-info/entry_points.txt,sha256=LENOkn88xzFQo-V59AKoA_F_cfYQTJYtrNTtf37YgHY,60
46
- anemoi_utils-0.4.32.dist-info/top_level.txt,sha256=DYn8VPs-fNwr7fNH9XIBqeXIwiYYd2E2k5-dUFFqUz0,7
47
- anemoi_utils-0.4.32.dist-info/RECORD,,
43
+ anemoi_utils-0.4.34.dist-info/licenses/LICENSE,sha256=8HznKF1Vi2IvfLsKNE5A2iVyiri3pRjRPvPC9kxs6qk,11354
44
+ anemoi_utils-0.4.34.dist-info/METADATA,sha256=2zvSY1iHHVcvLpaobfHCApsjwPUqeeg1UAy2FX0twWQ,15668
45
+ anemoi_utils-0.4.34.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
46
+ anemoi_utils-0.4.34.dist-info/entry_points.txt,sha256=LENOkn88xzFQo-V59AKoA_F_cfYQTJYtrNTtf37YgHY,60
47
+ anemoi_utils-0.4.34.dist-info/top_level.txt,sha256=DYn8VPs-fNwr7fNH9XIBqeXIwiYYd2E2k5-dUFFqUz0,7
48
+ anemoi_utils-0.4.34.dist-info/RECORD,,