climate-ref 0.6.1__py3-none-any.whl → 0.6.2__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.
- climate_ref/cli/__init__.py +3 -3
- climate_ref/cli/config.py +6 -6
- climate_ref/cli/datasets.py +9 -2
- climate_ref/cli/executions.py +12 -2
- climate_ref/cli/providers.py +4 -1
- climate_ref/cli/solve.py +4 -0
- climate_ref/config.py +2 -0
- climate_ref/executor/hpc.py +24 -12
- climate_ref/slurm.py +8 -4
- {climate_ref-0.6.1.dist-info → climate_ref-0.6.2.dist-info}/METADATA +4 -3
- {climate_ref-0.6.1.dist-info → climate_ref-0.6.2.dist-info}/RECORD +15 -15
- {climate_ref-0.6.1.dist-info → climate_ref-0.6.2.dist-info}/WHEEL +0 -0
- {climate_ref-0.6.1.dist-info → climate_ref-0.6.2.dist-info}/entry_points.txt +0 -0
- {climate_ref-0.6.1.dist-info → climate_ref-0.6.2.dist-info}/licenses/LICENCE +0 -0
- {climate_ref-0.6.1.dist-info → climate_ref-0.6.2.dist-info}/licenses/NOTICE +0 -0
climate_ref/cli/__init__.py
CHANGED
|
@@ -88,7 +88,7 @@ def build_app() -> typer.Typer:
|
|
|
88
88
|
:
|
|
89
89
|
The CLI app
|
|
90
90
|
"""
|
|
91
|
-
app = typer.Typer(name="
|
|
91
|
+
app = typer.Typer(name="ref", no_args_is_help=True)
|
|
92
92
|
|
|
93
93
|
app.command(name="solve")(solve.solve)
|
|
94
94
|
app.add_typer(config.app, name="config")
|
|
@@ -136,10 +136,10 @@ def main( # noqa: PLR0913
|
|
|
136
136
|
] = None,
|
|
137
137
|
) -> None:
|
|
138
138
|
"""
|
|
139
|
-
|
|
139
|
+
A CLI for the Assessment Fast Track Rapid Evaluation Framework
|
|
140
140
|
|
|
141
141
|
This CLI provides a number of commands for managing and executing diagnostics.
|
|
142
|
-
"""
|
|
142
|
+
""" # noqa: D401
|
|
143
143
|
if quiet:
|
|
144
144
|
log_level = LogLevel.Warning
|
|
145
145
|
if verbose:
|
climate_ref/cli/config.py
CHANGED
|
@@ -20,9 +20,9 @@ def list_(ctx: typer.Context) -> None:
|
|
|
20
20
|
print(config.dumps(defaults=True))
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
@app.command()
|
|
24
|
-
def update() -> None:
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
# @app.command()
|
|
24
|
+
# def update() -> None:
|
|
25
|
+
# """
|
|
26
|
+
# Update a configuration value
|
|
27
|
+
# """
|
|
28
|
+
# print("config")
|
climate_ref/cli/datasets.py
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
"""
|
|
2
2
|
View and ingest input datasets
|
|
3
|
+
|
|
4
|
+
The metadata from these datasets are stored in the database so that they can be used to determine
|
|
5
|
+
which executions are required for a given diagnostic without having to re-parse the datasets.
|
|
6
|
+
|
|
3
7
|
"""
|
|
4
8
|
|
|
5
9
|
import errno
|
|
@@ -105,9 +109,12 @@ def ingest( # noqa: PLR0913
|
|
|
105
109
|
] = False,
|
|
106
110
|
) -> None:
|
|
107
111
|
"""
|
|
108
|
-
Ingest a
|
|
112
|
+
Ingest a directory of datasets into the database
|
|
113
|
+
|
|
114
|
+
Each dataset will be loaded and validated using the specified dataset adapter.
|
|
115
|
+
This will extract metadata from the datasets and store it in the database.
|
|
109
116
|
|
|
110
|
-
|
|
117
|
+
A table of the datasets will be printed to the console at the end of the operation.
|
|
111
118
|
"""
|
|
112
119
|
config = ctx.obj.config
|
|
113
120
|
db = ctx.obj.database
|
climate_ref/cli/executions.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""
|
|
2
|
-
View
|
|
2
|
+
View execution groups and their results
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
import pathlib
|
|
@@ -29,11 +29,19 @@ console = Console()
|
|
|
29
29
|
@app.command()
|
|
30
30
|
def list_groups(
|
|
31
31
|
ctx: typer.Context,
|
|
32
|
-
column: Annotated[
|
|
32
|
+
column: Annotated[
|
|
33
|
+
list[str] | None,
|
|
34
|
+
typer.Option(help="Only include specified columns in the output"),
|
|
35
|
+
] = None,
|
|
33
36
|
limit: int = typer.Option(100, help="Limit the number of rows to display"),
|
|
34
37
|
) -> None:
|
|
35
38
|
"""
|
|
36
39
|
List the diagnostic execution groups that have been identified
|
|
40
|
+
|
|
41
|
+
The data catalog is sorted by the date that the execution group was created (first = newest).
|
|
42
|
+
If the `--column` option is provided, only the specified columns will be displayed.
|
|
43
|
+
|
|
44
|
+
The output will be in a tabular format.
|
|
37
45
|
"""
|
|
38
46
|
session = ctx.obj.database.session
|
|
39
47
|
|
|
@@ -178,6 +186,8 @@ def _log_panel(result_directory: pathlib.Path) -> Panel | None:
|
|
|
178
186
|
def inspect(ctx: typer.Context, execution_id: int) -> None:
|
|
179
187
|
"""
|
|
180
188
|
Inspect a specific execution group by its ID
|
|
189
|
+
|
|
190
|
+
This will display the execution details, datasets, results directory, and logs if available.
|
|
181
191
|
"""
|
|
182
192
|
config: Config = ctx.obj.config
|
|
183
193
|
session = ctx.obj.database.session
|
climate_ref/cli/providers.py
CHANGED
|
@@ -56,7 +56,10 @@ def create_env(
|
|
|
56
56
|
] = None,
|
|
57
57
|
) -> None:
|
|
58
58
|
"""
|
|
59
|
-
Create a
|
|
59
|
+
Create a conda environment containing the provider software.
|
|
60
|
+
|
|
61
|
+
If no provider is specified, all providers will be installed.
|
|
62
|
+
If the provider is up to date or does not use a virtual environment, it will be skipped.
|
|
60
63
|
"""
|
|
61
64
|
config = ctx.obj.config
|
|
62
65
|
db = ctx.obj.database
|
climate_ref/cli/solve.py
CHANGED
|
@@ -49,6 +49,10 @@ def solve( # noqa: PLR0913
|
|
|
49
49
|
|
|
50
50
|
This may trigger a number of additional calculations depending on what data has been ingested
|
|
51
51
|
since the last solve.
|
|
52
|
+
This command will block until all executions have been solved or the timeout is reached.
|
|
53
|
+
|
|
54
|
+
Filters can be applied to limit the diagnostics and providers that are considered, see the options
|
|
55
|
+
`--diagnostic` and `--provider` for more information.
|
|
52
56
|
"""
|
|
53
57
|
config = ctx.obj.config
|
|
54
58
|
db = ctx.obj.database
|
climate_ref/config.py
CHANGED
|
@@ -15,6 +15,7 @@ which always take precedence over any other configuration values.
|
|
|
15
15
|
# https://github.com/ESGF/esgf-download/blob/main/esgpull/config.py
|
|
16
16
|
|
|
17
17
|
import importlib.resources
|
|
18
|
+
import os
|
|
18
19
|
from pathlib import Path
|
|
19
20
|
from typing import TYPE_CHECKING, Any
|
|
20
21
|
|
|
@@ -64,6 +65,7 @@ def ensure_absolute_path(path: str | Path) -> Path:
|
|
|
64
65
|
"""
|
|
65
66
|
if isinstance(path, str):
|
|
66
67
|
path = Path(path)
|
|
68
|
+
path = Path(*[os.path.expandvars(p) for p in path.parts])
|
|
67
69
|
return path.resolve()
|
|
68
70
|
|
|
69
71
|
|
climate_ref/executor/hpc.py
CHANGED
|
@@ -7,9 +7,14 @@ If you want to
|
|
|
7
7
|
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
|
+
try:
|
|
11
|
+
import parsl
|
|
12
|
+
except ImportError: # pragma: no cover
|
|
13
|
+
raise ImportError("The HPCExecutor requires the `parsl` package")
|
|
14
|
+
|
|
10
15
|
import os
|
|
11
16
|
import time
|
|
12
|
-
from typing import Any
|
|
17
|
+
from typing import Any
|
|
13
18
|
|
|
14
19
|
import parsl
|
|
15
20
|
from loguru import logger
|
|
@@ -41,7 +46,7 @@ def _process_run(definition: ExecutionDefinition, log_level: str) -> ExecutionRe
|
|
|
41
46
|
except DiagnosticError as e: # pragma: no cover
|
|
42
47
|
# any diagnostic error will be caught here
|
|
43
48
|
logger.exception("Error running diagnostic")
|
|
44
|
-
|
|
49
|
+
raise e
|
|
45
50
|
|
|
46
51
|
|
|
47
52
|
def _to_float(x: Any) -> float | None:
|
|
@@ -264,20 +269,27 @@ class HPCExecutor:
|
|
|
264
269
|
# Iterate over a copy of the list and remove finished tasks
|
|
265
270
|
for result in results[:]:
|
|
266
271
|
if result.future.done():
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
272
|
+
# Cannot catch the execption raised by result.future.result
|
|
273
|
+
if result.future.exception() is None:
|
|
274
|
+
try:
|
|
275
|
+
execution_result = result.future.result(timeout=0)
|
|
276
|
+
except Exception as e:
|
|
277
|
+
# Something went wrong when attempting to run the execution
|
|
278
|
+
# This is likely a failure in the execution itself not the diagnostic
|
|
279
|
+
raise ExecutionError(
|
|
280
|
+
f"Failed to execute {result.definition.execution_slug()!r}"
|
|
281
|
+
) from e
|
|
282
|
+
else:
|
|
283
|
+
err = result.future.exception()
|
|
284
|
+
if isinstance(err, DiagnosticError):
|
|
285
|
+
execution_result = err.result
|
|
286
|
+
else:
|
|
287
|
+
execution_result = None
|
|
275
288
|
|
|
276
289
|
assert execution_result is not None, "Execution result should not be None"
|
|
277
290
|
assert isinstance(execution_result, ExecutionResult), (
|
|
278
291
|
"Execution result should be of type ExecutionResult"
|
|
279
292
|
)
|
|
280
|
-
|
|
281
293
|
# Process the result in the main process
|
|
282
294
|
# The results should be committed after each execution
|
|
283
295
|
with self.database.session.begin():
|
|
@@ -286,7 +298,7 @@ class HPCExecutor:
|
|
|
286
298
|
if result.execution_id
|
|
287
299
|
else None
|
|
288
300
|
)
|
|
289
|
-
process_result(self.config, self.database,
|
|
301
|
+
process_result(self.config, self.database, execution_result, execution)
|
|
290
302
|
logger.debug(f"Execution completed: {result}")
|
|
291
303
|
t.update(n=1)
|
|
292
304
|
results.remove(result)
|
climate_ref/slurm.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import importlib.util
|
|
2
|
+
import os
|
|
2
3
|
from typing import Any
|
|
3
4
|
|
|
4
5
|
HAS_REAL_SLURM = importlib.util.find_spec("pyslurm") is not None
|
|
@@ -85,10 +86,13 @@ class SlurmChecker:
|
|
|
85
86
|
return False
|
|
86
87
|
|
|
87
88
|
sample_acc = account_info[0]
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
user_name = os.environ["USER"]
|
|
90
|
+
|
|
91
|
+
if user_name:
|
|
92
|
+
for acc in account_info:
|
|
93
|
+
if acc.user == user_name:
|
|
94
|
+
sample_acc = acc
|
|
95
|
+
break
|
|
92
96
|
|
|
93
97
|
allowed_qoss = sample_acc.qos
|
|
94
98
|
if allowed_qoss is None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: climate-ref
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.2
|
|
4
4
|
Summary: Application which runs the CMIP Rapid Evaluation Framework
|
|
5
5
|
Author-email: Jared Lewis <jared.lewis@climate-resource.com>, Mika Pflueger <mika.pflueger@climate-resource.com>, Bouwe Andela <b.andela@esciencecenter.nl>, Jiwoo Lee <lee1043@llnl.gov>, Min Xu <xum1@ornl.gov>, Nathan Collier <collierno@ornl.gov>, Dora Hegedus <dora.hegedus@stfc.ac.uk>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -10,7 +10,8 @@ Classifier: Development Status :: 3 - Alpha
|
|
|
10
10
|
Classifier: Intended Audience :: Developers
|
|
11
11
|
Classifier: Intended Audience :: Science/Research
|
|
12
12
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
13
|
-
Classifier: Operating System ::
|
|
13
|
+
Classifier: Operating System :: MacOS :: MacOS X
|
|
14
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
14
15
|
Classifier: Programming Language :: Python
|
|
15
16
|
Classifier: Programming Language :: Python :: 3
|
|
16
17
|
Classifier: Programming Language :: Python :: 3.11
|
|
@@ -25,7 +26,7 @@ Requires-Dist: climate-ref-core
|
|
|
25
26
|
Requires-Dist: ecgtools>=2024.7.31
|
|
26
27
|
Requires-Dist: environs>=11.0.0
|
|
27
28
|
Requires-Dist: loguru>=0.7.2
|
|
28
|
-
Requires-Dist: parsl>=2025.5.19
|
|
29
|
+
Requires-Dist: parsl>=2025.5.19; sys_platform != 'win32'
|
|
29
30
|
Requires-Dist: platformdirs>=4.3.6
|
|
30
31
|
Requires-Dist: sqlalchemy>=2.0.36
|
|
31
32
|
Requires-Dist: tomlkit>=0.13.2
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
climate_ref/__init__.py,sha256=M45QGfl0KCPK48A8MjI08weNvZHMYH__GblraQMxsoM,808
|
|
2
2
|
climate_ref/_config_helpers.py,sha256=-atI5FX7SukhLE_jz_rL-EHQ7s0YYqKu3dSFYWxSyMU,6632
|
|
3
3
|
climate_ref/alembic.ini,sha256=WRvbwSIFuZ7hWNMnR2-yHPJAwYUnwhvRYBzkJhtpGdg,3535
|
|
4
|
-
climate_ref/config.py,sha256=
|
|
4
|
+
climate_ref/config.py,sha256=T1WzwFhzJ2-RKnOzyOmyUsdXrj_KDW2eycdPXZKnbf0,16954
|
|
5
5
|
climate_ref/constants.py,sha256=9RaNLgUSuQva7ki4eRW3TjOKeVP6T81QNiu0veB1zVk,111
|
|
6
6
|
climate_ref/database.py,sha256=b_6XHdr78Mo7KeLqQJ5DjLsySHPdQE83P8dRpdMfzfM,8661
|
|
7
7
|
climate_ref/provider_registry.py,sha256=dyfj4vU6unKHNXtT03HafQtAi3LilL37uvu3paCnmNY,4159
|
|
8
8
|
climate_ref/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
-
climate_ref/slurm.py,sha256=
|
|
9
|
+
climate_ref/slurm.py,sha256=XWXVPdXP-4BDib3bxYW9uPcAJdPpo1ixYZAI_y1cZuw,7305
|
|
10
10
|
climate_ref/solver.py,sha256=T5sQjweSvpUMG4q8MfbGjljxa5kBgKxNotT78PwyxqU,16804
|
|
11
11
|
climate_ref/testing.py,sha256=1b9lVCJlKxjJ7JGq6zDD2gK3BEM9ZVv1dbA-j6yb4Yk,4256
|
|
12
|
-
climate_ref/cli/__init__.py,sha256=
|
|
12
|
+
climate_ref/cli/__init__.py,sha256=fvENOeL4j7CMPANVxrDlWfaB0QUvvYgrWcm5ptbL0P8,4350
|
|
13
13
|
climate_ref/cli/_utils.py,sha256=6bIb8zEVvzXyKpv8MG58T-T2L2jH-G8WNrOOGpz3uCw,1918
|
|
14
|
-
climate_ref/cli/config.py,sha256=
|
|
15
|
-
climate_ref/cli/datasets.py,sha256=
|
|
16
|
-
climate_ref/cli/executions.py,sha256=
|
|
17
|
-
climate_ref/cli/providers.py,sha256
|
|
18
|
-
climate_ref/cli/solve.py,sha256=
|
|
14
|
+
climate_ref/cli/config.py,sha256=ak4Rn9S6fH23PkHHlI-pXuPiZYOvUB4r26eu3p525-M,532
|
|
15
|
+
climate_ref/cli/datasets.py,sha256=4iYQZ0ceoF-Cd8eSpS4Q8b9aLt_vEDUw5slzGw02DsY,8277
|
|
16
|
+
climate_ref/cli/executions.py,sha256=2MjwxCdRB-uVJUg7RluDIf_IsoclRn22ibJjk_nhfPo,7215
|
|
17
|
+
climate_ref/cli/providers.py,sha256=-5hQkJc01jON1bc1dk--tSWTesyiHOzZuYMb9Vxge9k,2613
|
|
18
|
+
climate_ref/cli/solve.py,sha256=ZTXrwDFDXNrX5GLMJTN9tFnpV3zlcZbEu2aF3JDJVxI,2367
|
|
19
19
|
climate_ref/dataset_registry/obs4ref_reference.txt,sha256=2zJMbsAsQ49KaWziX3CqrlILq9yN7S2ygmfV3V5rsnw,8395
|
|
20
20
|
climate_ref/dataset_registry/sample_data.txt,sha256=3JAHy14pRbLlo9-oNxUXLgZ_QOFJXUieEftBbapSY8E,20124
|
|
21
21
|
climate_ref/datasets/__init__.py,sha256=PV3u5ZmhyfcHbKqySgwVA8m4-naZgxzydLXSBqdTGLM,1171
|
|
@@ -25,7 +25,7 @@ climate_ref/datasets/obs4mips.py,sha256=CmMm4kopfb0yFsMSgUlHUm8clGJImBaodSkh6lAv
|
|
|
25
25
|
climate_ref/datasets/pmp_climatology.py,sha256=goHDc_3B2Wdiy_hmpERNvWDdDYZACPOyFDt3Du6nGc0,534
|
|
26
26
|
climate_ref/datasets/utils.py,sha256=iLJO7h4G3DWsRe9hIC4qkIyi5_zIW1ZMw-FDASLujtM,359
|
|
27
27
|
climate_ref/executor/__init__.py,sha256=PYtJs3oBS_GiUHbt8BF-6wJibpF6_vREm1Cg9TxVbLI,648
|
|
28
|
-
climate_ref/executor/hpc.py,sha256=
|
|
28
|
+
climate_ref/executor/hpc.py,sha256=4o90sCyoC4jlkem3BXNo4uwFZpIvOUGfrqYucB6EtU8,12251
|
|
29
29
|
climate_ref/executor/local.py,sha256=65LUl41YtURFb87YTWZQHjDpIRlIKJ5Ny51c9DZjy0s,8582
|
|
30
30
|
climate_ref/executor/result_handling.py,sha256=i7ZMX5vvyPY5gW-WWd-JHLi1BLviB9FXhn4FE8C9d4w,7787
|
|
31
31
|
climate_ref/executor/synchronous.py,sha256=o4TndsoKMu9AzJYLkusU9lRkgHCy6HcCP46tEs6o86U,1895
|
|
@@ -41,9 +41,9 @@ climate_ref/models/diagnostic.py,sha256=YB6xzbEXdpz2j-Ddf19RV8mAiWBrkmtRmiAEUV3t
|
|
|
41
41
|
climate_ref/models/execution.py,sha256=lRCpaKLSR7rZbuoL94GW76tm9wLMsSDoIOA7bIa6xgY,9848
|
|
42
42
|
climate_ref/models/metric_value.py,sha256=44OLcZz-qLx-p_9w7YWDKpD5S7Y9HyTKKsvSb77RBro,10190
|
|
43
43
|
climate_ref/models/provider.py,sha256=RAE2qAAxwObu-72CdK4kt5ACMmKYEn07WJm7DU9hF28,990
|
|
44
|
-
climate_ref-0.6.
|
|
45
|
-
climate_ref-0.6.
|
|
46
|
-
climate_ref-0.6.
|
|
47
|
-
climate_ref-0.6.
|
|
48
|
-
climate_ref-0.6.
|
|
49
|
-
climate_ref-0.6.
|
|
44
|
+
climate_ref-0.6.2.dist-info/METADATA,sha256=1yFQ4n5psYiBtO6jmhhEMdWkpOhM74sD_rE92XXm3Do,4505
|
|
45
|
+
climate_ref-0.6.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
46
|
+
climate_ref-0.6.2.dist-info/entry_points.txt,sha256=IaggEJlDIhoYWXdXJafacWbWtCcoEqUKceP1qD7_7vU,44
|
|
47
|
+
climate_ref-0.6.2.dist-info/licenses/LICENCE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
48
|
+
climate_ref-0.6.2.dist-info/licenses/NOTICE,sha256=4qTlax9aX2-mswYJuVrLqJ9jK1IkN5kSBqfVvYLF3Ws,128
|
|
49
|
+
climate_ref-0.6.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|