Skip to content

Commit d8751c5

Browse files
committed
Provide res-marg CLI via .cli and associated tools
- Integrate with existing `mix-models` CLI. - Remove duplicated code for model/scenario/version arguments, loading platform and scenario, etc. - Simplify tests.
1 parent 750ee3c commit d8751c5

File tree

3 files changed

+22
-44
lines changed

3 files changed

+22
-44
lines changed

message_ix_models/cli.py

+1
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ def _log_threads(k: int, n: int):
168168
"message_ix_models.report.cli",
169169
"message_ix_models.model.material.cli",
170170
"message_ix_models.testing.cli",
171+
"message_ix_models.tools.res_marg",
171172
"message_ix_models.util.pooch",
172173
]
173174

message_ix_models/tests/tools/test_res_marg.py

+7-11
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,20 @@
1-
from subprocess import CalledProcessError, check_call
2-
31
import pytest
42

53
from message_ix_models.tools.res_marg import main
64

75

8-
def test_cli() -> None:
6+
def test_cli(mix_models_cli) -> None:
97
"""Run :func:`.res_marg.main` via its command-line interface."""
108
command = [
11-
"python",
12-
"-m",
13-
"message_ix_models.tools.res_marg",
9+
"--model=model_name",
10+
"--scenario=scenario_name",
1411
"--version=123",
15-
"model_name",
16-
"scenario_name",
12+
"res-marg",
1713
]
1814

19-
# Fails: the model name, scenario name, and version do not exit
20-
with pytest.raises(CalledProcessError):
21-
check_call(command)
15+
# Fails: the model name, scenario name, and version do not exist
16+
with pytest.raises(RuntimeError):
17+
mix_models_cli.assert_exit_0(command)
2218

2319

2420
@pytest.mark.xfail(reason="Function does not run on the snapshot")

message_ix_models/tools/res_marg.py

+14-33
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
1-
"""Update the reserve margin."""
1+
"""Update the reserve margin.
2+
3+
:func:`main` can also be invoked using the CLI command
4+
:program:`mix-models --url=… res-marg`.
5+
"""
26

3-
import argparse
47
from typing import TYPE_CHECKING
58

9+
import click
10+
611
if TYPE_CHECKING:
712
from message_ix import Scenario
813

14+
from message_ix_models import Context
15+
916

1017
def main(scen: "Scenario", contin: float = 0.2) -> None:
1118
"""Update the reserve margin.
@@ -100,34 +107,8 @@ def main(scen: "Scenario", contin: float = 0.2) -> None:
100107
)
101108

102109

103-
if __name__ == "__main__":
104-
descr = """
105-
Reserve margin calculation
106-
107-
Example usage:
108-
python res_marg.py --version [X] [model name] [scenario name]
109-
110-
"""
111-
parser = argparse.ArgumentParser(
112-
description=descr, formatter_class=argparse.RawDescriptionHelpFormatter
113-
)
114-
version = "--version : string\n ix-scenario name"
115-
parser.add_argument("--version", help=version)
116-
model = "model : string\n ix-model name"
117-
parser.add_argument("model", help=model)
118-
scenario = "scenario : string\n ix-scenario name"
119-
parser.add_argument("scenario", help=scenario)
120-
121-
# parse cli
122-
args = parser.parse_args()
123-
model = args.model
124-
scenario = args.scenario
125-
version = int(args.version) if args.version else None
126-
127-
import ixmp
128-
import message_ix
129-
130-
mp = ixmp.Platform()
131-
scen = message_ix.Scenario(mp, model, scenario, version=version, cache=True)
132-
133-
main(scen)
110+
@click.command("res-marg")
111+
@click.pass_obj
112+
def cli(ctx: "Context"):
113+
"""Reserve margin calculation."""
114+
main(ctx.get_scenario())

0 commit comments

Comments
 (0)