Skip to content

Commit 2743c5f

Browse files
authored
Merge pull request #236 from Paperspace/PS-13030-Overwrite_yaml_options_in_terminal_line
Overvrite yaml options in terminal
2 parents 5835597 + 41ae635 commit 2743c5f

File tree

2 files changed

+48
-4
lines changed

2 files changed

+48
-4
lines changed

gradient/cli/common.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ def get_option_name(options_strings):
6767
class ReadValueFromConfigFile(click.Parameter):
6868
def handle_parse_result(self, ctx, opts, args):
6969
config_file = ctx.params.get(OPTIONS_FILE_PARAMETER_NAME)
70-
if config_file:
70+
if self.should_read_value_from_file(opts, args, config_file):
7171
with open(config_file) as f:
7272
config_data = yaml.load(f, Loader=yaml.FullLoader)
7373
option_name = get_option_name(self.opts)
@@ -89,8 +89,15 @@ def handle_parse_result(self, ctx, opts, args):
8989

9090
opts[self.name] = value
9191

92-
return super(ReadValueFromConfigFile, self).handle_parse_result(
92+
rv = super(ReadValueFromConfigFile, self).handle_parse_result(
9393
ctx, opts, args)
94+
return rv
95+
96+
def should_read_value_from_file(self, opts, args, config_file):
97+
"""
98+
:rtype: bool
99+
"""
100+
raise NotImplementedError
94101

95102

96103
class ColorExtrasInCommandHelpMixin(object):
@@ -127,11 +134,13 @@ def _color_str(self, s):
127134

128135

129136
class GradientArgument(ColorExtrasInCommandHelpMixin, ReadValueFromConfigFile, click.Argument):
130-
pass
137+
def should_read_value_from_file(self, opts, args, config_file):
138+
return opts.get(self.name) in (None, ()) and config_file
131139

132140

133141
class GradientOption(ColorExtrasInCommandHelpMixin, ReadValueFromConfigFile, click.Option):
134-
pass
142+
def should_read_value_from_file(self, opts, args, config_file):
143+
return self.name not in opts and config_file
135144

136145

137146
api_key_option = click.option(
@@ -207,6 +216,7 @@ def options_file(f):
207216
click.option(
208217
"--" + OPTIONS_FILE_OPTION_NAME,
209218
OPTIONS_FILE_PARAMETER_NAME,
219+
is_eager=True,
210220
help="Path to YAML file with predefined options",
211221
type=click.Path(exists=True, resolve_path=True)
212222
),

tests/functional/test_experiments.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import copy
12
import os
23
import shutil
34
import tempfile
@@ -98,6 +99,11 @@ class TestExperimentsCreateSingleNode(object):
9899
"experiments", "create", "singlenode",
99100
"--optionsFile", # path added in test,
100101
]
102+
FULL_OPTIONS_COMMAND_WITH_OPTIONS_FILE_AND_SOME_VALUES_OVERWRITTEN_IN_LINE = [
103+
"experiments", "create", "singlenode",
104+
"--name", "some_other_name",
105+
"--optionsFile", # path added in test,
106+
]
101107
BASIC_OPTIONS_REQUEST = {
102108
"projectHandle": u"testHandle",
103109
"container": u"testContainer",
@@ -173,6 +179,29 @@ def test_should_read_options_from_config_file(
173179
data=None)
174180
assert result.exit_code == 0, result.exc_info
175181

182+
@mock.patch("gradient.api_sdk.clients.http_client.requests.post")
183+
def test_should_read_options_from_config_file_and_overwrite_options_with_values_provided_in_terminal(
184+
self, post_patched, create_single_node_experiment_config_path):
185+
post_patched.return_value = MockResponse(self.RESPONSE_JSON_200)
186+
request_json = copy.deepcopy(self.FULL_OPTIONS_REQUEST)
187+
request_json["name"] = "some_other_name"
188+
request_json["projectHandle"] = "some_other_project_id"
189+
190+
command = self.FULL_OPTIONS_COMMAND_WITH_OPTIONS_FILE_AND_SOME_VALUES_OVERWRITTEN_IN_LINE[:]
191+
command = command[:] + [create_single_node_experiment_config_path, "--projectId", "some_other_project_id"]
192+
193+
runner = CliRunner()
194+
result = runner.invoke(cli.cli, command)
195+
196+
assert self.EXPECTED_STDOUT in result.output, result.exc_info
197+
post_patched.assert_called_once_with(self.URL_V2,
198+
headers=EXPECTED_HEADERS_WITH_CHANGED_API_KEY,
199+
json=request_json,
200+
params=None,
201+
files=None,
202+
data=None)
203+
assert result.exit_code == 0, result.exc_info
204+
176205
@mock.patch("gradient.api_sdk.clients.http_client.requests.post")
177206
def test_should_send_proper_data_and_print_message_when_create_experiment_was_run_with_full_options(self,
178207
post_patched):
@@ -953,6 +982,11 @@ class TestExperimentsCreateAndStartSingleNode(TestExperimentsCreateSingleNode):
953982
"experiments", "run", "singlenode",
954983
"--optionsFile", # path added in test,
955984
]
985+
FULL_OPTIONS_COMMAND_WITH_OPTIONS_FILE_AND_SOME_VALUES_OVERWRITTEN_IN_LINE = [
986+
"experiments", "run", "singlenode",
987+
"--name", "some_other_name",
988+
"--optionsFile", # path added in test,
989+
]
956990
EXPECTED_STDOUT = "New experiment created and started with ID: sadkfhlskdjh\n"
957991

958992

0 commit comments

Comments
 (0)