anemoi-utils 0.2.0__py3-none-any.whl → 0.3.0__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/__main__.py CHANGED
@@ -8,64 +8,20 @@
8
8
  # nor does it submit to any jurisdiction.
9
9
  #
10
10
 
11
-
12
- import argparse
13
- import logging
14
- import sys
15
- import traceback
11
+ from anemoi.utils.cli import cli_main
12
+ from anemoi.utils.cli import make_parser
16
13
 
17
14
  from . import __version__
18
15
  from .commands import COMMANDS
19
16
 
20
- LOG = logging.getLogger(__name__)
21
-
22
-
23
- def main():
24
- parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
25
-
26
- parser.add_argument(
27
- "--version",
28
- "-V",
29
- action="store_true",
30
- help="show the version and exit",
31
- )
32
- parser.add_argument(
33
- "--debug",
34
- "-d",
35
- action="store_true",
36
- help="Debug mode",
37
- )
38
17
 
39
- subparsers = parser.add_subparsers(help="commands:", dest="command")
40
- for name, command in COMMANDS.items():
41
- command_parser = subparsers.add_parser(name, help=command.__doc__)
42
- command.add_arguments(command_parser)
18
+ # For read-the-docs
19
+ def create_parser():
20
+ return make_parser(__doc__, COMMANDS)
43
21
 
44
- args = parser.parse_args()
45
22
 
46
- if args.version:
47
- print(__version__)
48
- return
49
-
50
- if args.command is None:
51
- parser.print_help()
52
- return
53
-
54
- cmd = COMMANDS[args.command]
55
-
56
- logging.basicConfig(
57
- format="%(asctime)s %(levelname)s %(message)s",
58
- datefmt="%Y-%m-%d %H:%M:%S",
59
- level=logging.DEBUG if args.debug else logging.INFO,
60
- )
61
-
62
- try:
63
- cmd.run(args)
64
- except ValueError as e:
65
- traceback.print_exc()
66
- LOG.error("\n💣 %s", str(e).lstrip())
67
- LOG.error("💣 Exiting")
68
- sys.exit(1)
23
+ def main():
24
+ cli_main(__version__, __doc__, COMMANDS)
69
25
 
70
26
 
71
27
  if __name__ == "__main__":
anemoi/utils/_version.py CHANGED
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.2.0'
16
- __version_tuple__ = version_tuple = (0, 2, 0)
15
+ __version__ = version = '0.3.0'
16
+ __version_tuple__ = version_tuple = (0, 3, 0)
anemoi/utils/cli.py ADDED
@@ -0,0 +1,126 @@
1
+ # (C) Copyright 2024 European Centre for Medium-Range Weather Forecasts.
2
+ # This software is licensed under the terms of the Apache Licence Version 2.0
3
+ # which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
4
+ # In applying this licence, ECMWF does not waive the privileges and immunities
5
+ # granted to it by virtue of its status as an intergovernmental organisation
6
+ # nor does it submit to any jurisdiction.
7
+
8
+ import argparse
9
+ import importlib
10
+ import logging
11
+ import os
12
+ import sys
13
+ import traceback
14
+
15
+ LOG = logging.getLogger(__name__)
16
+
17
+
18
+ class Command:
19
+ def run(self, args):
20
+ raise NotImplementedError(f"Command not implemented: {args.command}")
21
+
22
+
23
+ def make_parser(description, commands):
24
+ parser = argparse.ArgumentParser(
25
+ description=description,
26
+ formatter_class=argparse.RawDescriptionHelpFormatter,
27
+ )
28
+
29
+ parser.add_argument(
30
+ "--version",
31
+ "-V",
32
+ action="store_true",
33
+ help="show the version and exit",
34
+ )
35
+ parser.add_argument(
36
+ "--debug",
37
+ "-d",
38
+ action="store_true",
39
+ help="Debug mode",
40
+ )
41
+
42
+ subparsers = parser.add_subparsers(help="commands:", dest="command")
43
+ for name, command in commands.items():
44
+ command_parser = subparsers.add_parser(name, help=command.__doc__)
45
+ command.add_arguments(command_parser)
46
+
47
+ return parser
48
+
49
+
50
+ class Failed(Command):
51
+ def __init__(self, name, error):
52
+ self.name = name
53
+ self.error = error
54
+
55
+ def add_arguments(self, command_parser):
56
+ command_parser.add_argument("x", nargs=argparse.REMAINDER)
57
+
58
+ def run(self, args):
59
+ print(f"Command '{self.name}' not available: {self.error}")
60
+ sys.exit(1)
61
+
62
+
63
+ def register_commands(here, package, select, fail=None):
64
+ result = {}
65
+ not_available = {}
66
+
67
+ for p in os.listdir(here):
68
+ full = os.path.join(here, p)
69
+ if p.startswith("_"):
70
+ continue
71
+ if not (p.endswith(".py") or (os.path.isdir(full) and os.path.exists(os.path.join(full, "__init__.py")))):
72
+ continue
73
+
74
+ name, _ = os.path.splitext(p)
75
+
76
+ try:
77
+ imported = importlib.import_module(
78
+ f".{name}",
79
+ package=package,
80
+ )
81
+ except ImportError as e:
82
+ not_available[name] = e
83
+ continue
84
+
85
+ obj = select(imported)
86
+ if obj is not None:
87
+ result[name] = obj
88
+
89
+ for name, e in not_available.items():
90
+ if fail is None:
91
+ pass
92
+ if callable(fail):
93
+ result[name] = fail(name, e)
94
+
95
+ return result
96
+
97
+
98
+ def cli_main(version, description, commands):
99
+ parser = make_parser(description, commands)
100
+ args = parser.parse_args()
101
+
102
+ if args.version:
103
+ print(version)
104
+ return
105
+
106
+ if args.command is None:
107
+ parser.print_help()
108
+ return
109
+
110
+ cmd = commands[args.command]
111
+
112
+ logging.basicConfig(
113
+ format="%(asctime)s %(levelname)s %(message)s",
114
+ datefmt="%Y-%m-%d %H:%M:%S",
115
+ level=logging.DEBUG if args.debug else logging.INFO,
116
+ )
117
+
118
+ try:
119
+ cmd.run(args)
120
+ except ValueError as e:
121
+ traceback.print_exc()
122
+ LOG.error("\n💣 %s", str(e).lstrip())
123
+ LOG.error("💣 Exiting")
124
+ sys.exit(1)
125
+
126
+ sys.exit(0)
@@ -8,69 +8,15 @@
8
8
  # nor does it submit to any jurisdiction.
9
9
  #
10
10
 
11
- import argparse
12
- import importlib
13
- import logging
14
11
  import os
15
- import sys
16
12
 
17
- LOG = logging.getLogger(__name__)
13
+ from anemoi.utils.cli import Command
14
+ from anemoi.utils.cli import Failed
15
+ from anemoi.utils.cli import register_commands
18
16
 
17
+ __all__ = ["Command"]
19
18
 
20
- def register(here, package, select, fail=None):
21
- result = {}
22
- not_available = {}
23
-
24
- for p in os.listdir(here):
25
- full = os.path.join(here, p)
26
- if p.startswith("_"):
27
- continue
28
- if not (p.endswith(".py") or (os.path.isdir(full) and os.path.exists(os.path.join(full, "__init__.py")))):
29
- continue
30
-
31
- name, _ = os.path.splitext(p)
32
-
33
- try:
34
- imported = importlib.import_module(
35
- f".{name}",
36
- package=package,
37
- )
38
- except ImportError as e:
39
- not_available[name] = e
40
- continue
41
-
42
- obj = select(imported)
43
- if obj is not None:
44
- result[name] = obj
45
-
46
- for name, e in not_available.items():
47
- if fail is None:
48
- pass
49
- if callable(fail):
50
- result[name] = fail(name, e)
51
-
52
- return result
53
-
54
-
55
- class Command:
56
- def run(self, args):
57
- raise NotImplementedError(f"Command not implemented: {args.command}")
58
-
59
-
60
- class Failed(Command):
61
- def __init__(self, name, error):
62
- self.name = name
63
- self.error = error
64
-
65
- def add_arguments(self, command_parser):
66
- command_parser.add_argument("x", nargs=argparse.REMAINDER)
67
-
68
- def run(self, args):
69
- print(f"Command '{self.name}' not available: {self.error}")
70
- sys.exit(1)
71
-
72
-
73
- COMMANDS = register(
19
+ COMMANDS = register_commands(
74
20
  os.path.dirname(__file__),
75
21
  __name__,
76
22
  lambda x: x.command(),
anemoi/utils/timer.py CHANGED
@@ -16,6 +16,8 @@ LOGGER = logging.getLogger(__name__)
16
16
 
17
17
 
18
18
  class Timer:
19
+ """Context manager to measure elapsed time."""
20
+
19
21
  def __init__(self, title, logger=LOGGER):
20
22
  self.title = title
21
23
  self.start = time.time()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: anemoi-utils
3
- Version: 0.2.0
3
+ Version: 0.3.0
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
@@ -205,51 +205,54 @@ License: Apache License
205
205
  See the License for the specific language governing permissions and
206
206
  limitations under the License.
207
207
 
208
- Project-URL: Homepage, https://github.com/ecmwf/anemoi-utils/
209
208
  Project-URL: Documentation, https://anemoi-utils.readthedocs.io/
210
- Project-URL: Repository, https://github.com/ecmwf/anemoi-utils/
209
+ Project-URL: Homepage, https://github.com/ecmwf/anemoi-utils/
211
210
  Project-URL: Issues, https://github.com/ecmwf/anemoi-utils/issues
212
- Keywords: tools,ai
211
+ Project-URL: Repository, https://github.com/ecmwf/anemoi-utils/
212
+ Keywords: ai,tools
213
213
  Classifier: Development Status :: 4 - Beta
214
214
  Classifier: Intended Audience :: Developers
215
215
  Classifier: License :: OSI Approved :: Apache Software License
216
- Classifier: Programming Language :: Python :: 3
216
+ Classifier: Operating System :: OS Independent
217
+ Classifier: Programming Language :: Python :: 3 :: Only
217
218
  Classifier: Programming Language :: Python :: 3.9
218
219
  Classifier: Programming Language :: Python :: 3.10
219
220
  Classifier: Programming Language :: Python :: 3.11
221
+ Classifier: Programming Language :: Python :: 3.12
220
222
  Classifier: Programming Language :: Python :: Implementation :: CPython
221
223
  Classifier: Programming Language :: Python :: Implementation :: PyPy
222
- Classifier: Operating System :: OS Independent
223
224
  Requires-Python: >=3.9
224
225
  License-File: LICENSE
225
- Requires-Dist: tomli
226
226
  Requires-Dist: pyyaml
227
+ Requires-Dist: tomli
227
228
  Requires-Dist: tqdm
228
229
  Provides-Extra: all
229
- Requires-Dist: tomli ; extra == 'all'
230
- Requires-Dist: GitPython ; extra == 'all'
230
+ Requires-Dist: gitpython ; extra == 'all'
231
231
  Requires-Dist: nvsmi ; extra == 'all'
232
- Requires-Dist: termcolor ; extra == 'all'
232
+ Requires-Dist: pyyaml ; extra == 'all'
233
233
  Requires-Dist: requests ; extra == 'all'
234
+ Requires-Dist: termcolor ; extra == 'all'
235
+ Requires-Dist: tomli ; extra == 'all'
236
+ Requires-Dist: tqdm ; extra == 'all'
234
237
  Provides-Extra: dev
235
- Requires-Dist: tomli ; extra == 'dev'
236
- Requires-Dist: GitPython ; extra == 'dev'
238
+ Requires-Dist: gitpython ; extra == 'dev'
237
239
  Requires-Dist: nvsmi ; extra == 'dev'
238
- Requires-Dist: termcolor ; extra == 'dev'
239
240
  Requires-Dist: requests ; extra == 'dev'
241
+ Requires-Dist: termcolor ; extra == 'dev'
242
+ Requires-Dist: tomli ; extra == 'dev'
240
243
  Provides-Extra: docs
241
- Requires-Dist: tomli ; extra == 'docs'
242
- Requires-Dist: termcolor ; extra == 'docs'
243
- Requires-Dist: requests ; extra == 'docs'
244
- Requires-Dist: sphinx ; extra == 'docs'
245
- Requires-Dist: sphinx-rtd-theme ; extra == 'docs'
246
244
  Requires-Dist: nbsphinx ; extra == 'docs'
247
245
  Requires-Dist: pandoc ; extra == 'docs'
246
+ Requires-Dist: requests ; extra == 'docs'
247
+ Requires-Dist: sphinx ; extra == 'docs'
248
248
  Requires-Dist: sphinx-argparse ; extra == 'docs'
249
+ Requires-Dist: sphinx-rtd-theme ; extra == 'docs'
250
+ Requires-Dist: termcolor ; extra == 'docs'
251
+ Requires-Dist: tomli ; extra == 'docs'
249
252
  Provides-Extra: grib
250
253
  Requires-Dist: requests ; extra == 'grib'
251
254
  Provides-Extra: provenance
252
- Requires-Dist: GitPython ; extra == 'provenance'
255
+ Requires-Dist: gitpython ; extra == 'provenance'
253
256
  Requires-Dist: nvsmi ; extra == 'provenance'
254
257
  Provides-Extra: text
255
258
  Requires-Dist: termcolor ; extra == 'text'
@@ -1,22 +1,23 @@
1
1
  anemoi/utils/__init__.py,sha256=zZZpbKIoGWwdCOuo6YSruLR7C0GzvzI1Wzhyqaa0K7M,456
2
- anemoi/utils/__main__.py,sha256=CGl8WF7rWMx9EoArysla0-ThjUFtEZUEGM58LbdU488,1798
3
- anemoi/utils/_version.py,sha256=H-qsvrxCpdhaQzyddR-yajEqI71hPxLa4KxzpP3uS1g,411
2
+ anemoi/utils/__main__.py,sha256=cLA2PidDTOUHaDGzd0_E5iioKYNe-PSTv567Y2fuwQk,723
3
+ anemoi/utils/_version.py,sha256=Jk2iAU7m-7Vx9XV1TtdD9ZoJraIncDq_4_Wd-qtUotg,411
4
4
  anemoi/utils/caching.py,sha256=HrC9aFHlcCTaM2Z5u0ivGIXz7eFu35UQQhUuwwuG2pk,1743
5
5
  anemoi/utils/checkpoints.py,sha256=1_3mg4B-ykTVfIvIUEv7IxGyREx_ZcilVbB3U-V6O6I,5165
6
+ anemoi/utils/cli.py,sha256=39THXs5SVtJ3L4ugemgbRIlK4ivEGraSsu5ns9KUn68,3271
6
7
  anemoi/utils/config.py,sha256=XEesqODvkuE3ZA7dnEnZ-ooBRtU6ecPmkfP65FtialA,2147
7
8
  anemoi/utils/dates.py,sha256=Ot9OTY1uFvHxW1EU4DPv3oUqmzvkXTwKuwhlfVlY788,8426
8
9
  anemoi/utils/grib.py,sha256=gVfo4KYQv31iRyoqRDwk5tiqZDUgOIvhag_kO0qjYD0,3067
9
10
  anemoi/utils/humanize.py,sha256=LD6dGnqChxA5j3tMhSybsAGRQzi33d_qS9pUoUHubkc,10330
10
11
  anemoi/utils/provenance.py,sha256=v54L9jF1JgYcclOhg3iojRl1v3ajbiWz_oc289xTgO4,9574
11
12
  anemoi/utils/text.py,sha256=pGWtDvRFoDxAnSuZJiA-GOGJOJLHsw2dAm0tfVvPKno,8599
12
- anemoi/utils/timer.py,sha256=5aNdcxVmiCijRmqp0URmsqsDypLUJgME0GSn9bk8zxo,920
13
- anemoi/utils/commands/__init__.py,sha256=Pc5bhVgW92ox1lMR5WUOLuhiY2HT6PsadSHclyw99Vc,1983
13
+ anemoi/utils/timer.py,sha256=JKOgFkpJxmVRn57DEBolmTGwr25P-ePTWASBd8CLeqM,972
14
+ anemoi/utils/commands/__init__.py,sha256=qAybFZPBBQs0dyx7dZ3X5JsLpE90pwrqt1vSV7cqEIw,706
14
15
  anemoi/utils/commands/checkpoint.py,sha256=SEnAizU3WklqMXUjmIh4eNrgBVwmheKG9gEBS90zwYU,1741
15
16
  anemoi/utils/mars/__init__.py,sha256=RAeY8gJ7ZvsPlcIvrQ4fy9xVHs3SphTAPw_XJDtNIKo,1750
16
17
  anemoi/utils/mars/mars.yaml,sha256=R0dujp75lLA4wCWhPeOQnzJ45WZAYLT8gpx509cBFlc,66
17
- anemoi_utils-0.2.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
18
- anemoi_utils-0.2.0.dist-info/METADATA,sha256=7IO_KqlBHcAKCmdszjmE5Zxe5G_ox2QOwKn16mgBIa4,15174
19
- anemoi_utils-0.2.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
20
- anemoi_utils-0.2.0.dist-info/entry_points.txt,sha256=LENOkn88xzFQo-V59AKoA_F_cfYQTJYtrNTtf37YgHY,60
21
- anemoi_utils-0.2.0.dist-info/top_level.txt,sha256=DYn8VPs-fNwr7fNH9XIBqeXIwiYYd2E2k5-dUFFqUz0,7
22
- anemoi_utils-0.2.0.dist-info/RECORD,,
18
+ anemoi_utils-0.3.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
19
+ anemoi_utils-0.3.0.dist-info/METADATA,sha256=1NyB5Hj8UIpWFzmZdyoAjAPmIEkLabl9AhNBruFLo88,15309
20
+ anemoi_utils-0.3.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
21
+ anemoi_utils-0.3.0.dist-info/entry_points.txt,sha256=LENOkn88xzFQo-V59AKoA_F_cfYQTJYtrNTtf37YgHY,60
22
+ anemoi_utils-0.3.0.dist-info/top_level.txt,sha256=DYn8VPs-fNwr7fNH9XIBqeXIwiYYd2E2k5-dUFFqUz0,7
23
+ anemoi_utils-0.3.0.dist-info/RECORD,,