nextmv 1.0.0.dev3__py3-none-any.whl → 1.0.0.dev4__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.
Files changed (115) hide show
  1. nextmv/__about__.py +1 -1
  2. nextmv/cli/CONTRIBUTING.md +81 -29
  3. nextmv/cli/cloud/acceptance/create.py +20 -22
  4. nextmv/cli/cloud/acceptance/delete.py +7 -8
  5. nextmv/cli/cloud/acceptance/get.py +9 -10
  6. nextmv/cli/cloud/acceptance/list.py +3 -3
  7. nextmv/cli/cloud/acceptance/update.py +6 -6
  8. nextmv/cli/cloud/account/__init__.py +3 -3
  9. nextmv/cli/cloud/account/create.py +11 -11
  10. nextmv/cli/cloud/account/delete.py +6 -7
  11. nextmv/cli/cloud/account/get.py +3 -3
  12. nextmv/cli/cloud/account/update.py +5 -5
  13. nextmv/cli/cloud/app/create.py +25 -26
  14. nextmv/cli/cloud/app/delete.py +5 -6
  15. nextmv/cli/cloud/app/exists.py +2 -2
  16. nextmv/cli/cloud/app/get.py +2 -2
  17. nextmv/cli/cloud/app/list.py +3 -3
  18. nextmv/cli/cloud/app/push.py +269 -45
  19. nextmv/cli/cloud/app/update.py +12 -12
  20. nextmv/cli/cloud/batch/create.py +26 -28
  21. nextmv/cli/cloud/batch/delete.py +5 -6
  22. nextmv/cli/cloud/batch/get.py +8 -8
  23. nextmv/cli/cloud/batch/list.py +3 -3
  24. nextmv/cli/cloud/batch/metadata.py +4 -4
  25. nextmv/cli/cloud/batch/update.py +6 -6
  26. nextmv/cli/cloud/data/__init__.py +1 -1
  27. nextmv/cli/cloud/data/upload.py +15 -15
  28. nextmv/cli/cloud/ensemble/__init__.py +2 -0
  29. nextmv/cli/cloud/ensemble/create.py +21 -22
  30. nextmv/cli/cloud/ensemble/delete.py +5 -6
  31. nextmv/cli/cloud/ensemble/get.py +4 -4
  32. nextmv/cli/cloud/ensemble/list.py +63 -0
  33. nextmv/cli/cloud/ensemble/update.py +9 -9
  34. nextmv/cli/cloud/input_set/create.py +20 -22
  35. nextmv/cli/cloud/input_set/get.py +3 -3
  36. nextmv/cli/cloud/input_set/list.py +3 -3
  37. nextmv/cli/cloud/input_set/update.py +24 -24
  38. nextmv/cli/cloud/instance/create.py +14 -15
  39. nextmv/cli/cloud/instance/delete.py +5 -6
  40. nextmv/cli/cloud/instance/exists.py +2 -2
  41. nextmv/cli/cloud/instance/get.py +2 -2
  42. nextmv/cli/cloud/instance/list.py +3 -3
  43. nextmv/cli/cloud/instance/update.py +14 -14
  44. nextmv/cli/cloud/managed_input/create.py +14 -16
  45. nextmv/cli/cloud/managed_input/delete.py +6 -7
  46. nextmv/cli/cloud/managed_input/get.py +3 -3
  47. nextmv/cli/cloud/managed_input/list.py +3 -3
  48. nextmv/cli/cloud/managed_input/update.py +9 -9
  49. nextmv/cli/cloud/run/cancel.py +2 -2
  50. nextmv/cli/cloud/run/create.py +32 -33
  51. nextmv/cli/cloud/run/get.py +8 -8
  52. nextmv/cli/cloud/run/input.py +4 -4
  53. nextmv/cli/cloud/run/list.py +6 -6
  54. nextmv/cli/cloud/run/logs.py +9 -10
  55. nextmv/cli/cloud/run/metadata.py +4 -4
  56. nextmv/cli/cloud/run/track.py +32 -33
  57. nextmv/cli/cloud/scenario/create.py +21 -21
  58. nextmv/cli/cloud/scenario/delete.py +5 -6
  59. nextmv/cli/cloud/scenario/get.py +8 -8
  60. nextmv/cli/cloud/scenario/list.py +3 -3
  61. nextmv/cli/cloud/scenario/metadata.py +4 -4
  62. nextmv/cli/cloud/scenario/update.py +6 -6
  63. nextmv/cli/cloud/secrets/create.py +17 -17
  64. nextmv/cli/cloud/secrets/delete.py +5 -6
  65. nextmv/cli/cloud/secrets/get.py +4 -4
  66. nextmv/cli/cloud/secrets/list.py +3 -3
  67. nextmv/cli/cloud/secrets/update.py +17 -20
  68. nextmv/cli/cloud/shadow/create.py +31 -31
  69. nextmv/cli/cloud/shadow/delete.py +5 -6
  70. nextmv/cli/cloud/shadow/get.py +2 -2
  71. nextmv/cli/cloud/shadow/list.py +3 -3
  72. nextmv/cli/cloud/shadow/metadata.py +4 -4
  73. nextmv/cli/cloud/shadow/start.py +3 -3
  74. nextmv/cli/cloud/shadow/stop.py +4 -6
  75. nextmv/cli/cloud/shadow/update.py +6 -6
  76. nextmv/cli/cloud/switchback/create.py +19 -15
  77. nextmv/cli/cloud/switchback/delete.py +5 -6
  78. nextmv/cli/cloud/switchback/get.py +3 -3
  79. nextmv/cli/cloud/switchback/list.py +3 -3
  80. nextmv/cli/cloud/switchback/metadata.py +6 -6
  81. nextmv/cli/cloud/switchback/start.py +4 -4
  82. nextmv/cli/cloud/switchback/stop.py +4 -6
  83. nextmv/cli/cloud/switchback/update.py +6 -6
  84. nextmv/cli/cloud/upload/create.py +2 -2
  85. nextmv/cli/cloud/version/create.py +9 -10
  86. nextmv/cli/cloud/version/delete.py +5 -6
  87. nextmv/cli/cloud/version/exists.py +2 -2
  88. nextmv/cli/cloud/version/get.py +2 -2
  89. nextmv/cli/cloud/version/list.py +3 -3
  90. nextmv/cli/cloud/version/update.py +8 -8
  91. nextmv/cli/community/clone.py +12 -10
  92. nextmv/cli/community/list.py +9 -9
  93. nextmv/cli/configuration/config.py +43 -10
  94. nextmv/cli/configuration/create.py +3 -3
  95. nextmv/cli/configuration/delete.py +7 -7
  96. nextmv/cli/configuration/list.py +3 -3
  97. nextmv/cli/confirm.py +32 -0
  98. nextmv/cli/main.py +27 -36
  99. nextmv/cli/message.py +2 -2
  100. nextmv/cli/version.py +1 -1
  101. nextmv/cloud/application/__init__.py +190 -54
  102. nextmv/cloud/application/_batch_scenario.py +2 -2
  103. nextmv/cloud/application/_instance.py +2 -2
  104. nextmv/cloud/application/_managed_input.py +1 -1
  105. nextmv/cloud/application/_shadow.py +1 -1
  106. nextmv/cloud/application/_switchback.py +11 -3
  107. nextmv/cloud/application/_version.py +3 -2
  108. nextmv/cloud/shadow.py +43 -4
  109. nextmv/cloud/switchback.py +46 -9
  110. {nextmv-1.0.0.dev3.dist-info → nextmv-1.0.0.dev4.dist-info}/METADATA +1 -1
  111. nextmv-1.0.0.dev4.dist-info/RECORD +183 -0
  112. nextmv-1.0.0.dev3.dist-info/RECORD +0 -181
  113. {nextmv-1.0.0.dev3.dist-info → nextmv-1.0.0.dev4.dist-info}/WHEEL +0 -0
  114. {nextmv-1.0.0.dev3.dist-info → nextmv-1.0.0.dev4.dist-info}/entry_points.txt +0 -0
  115. {nextmv-1.0.0.dev3.dist-info → nextmv-1.0.0.dev4.dist-info}/licenses/LICENSE +0 -0
@@ -109,7 +109,7 @@ def create(
109
109
  "--wait",
110
110
  "-w",
111
111
  help="Wait for the batch experiment to complete. Results are printed to [magenta]stdout[/magenta]. "
112
- "Specify output location with [code]--output[/code].",
112
+ "Specify output location with --output.",
113
113
  rich_help_panel="Output control",
114
114
  ),
115
115
  ] = False,
@@ -122,21 +122,19 @@ def create(
122
122
  configurations. Each run is defined by a combination of input, instance or
123
123
  version, and optional configuration options.
124
124
 
125
- Use the [code]--wait[/code] flag to wait for the batch experiment to
126
- complete, polling for results. Using the [code]--output[/code] flag will
127
- also activate waiting, and allows you to specify a destination file for the
128
- results.
125
+ Use the --wait flag to wait for the batch experiment to complete, polling
126
+ for results. Using the --output flag will also activate waiting, and allows
127
+ you to specify a destination file for the results.
129
128
 
130
129
  [bold][underline]Runs[/underline][/bold]
131
130
 
132
- Runs are provided as [magenta]json[/magenta] objects using the
133
- [code]--runs[/code] flag. Each run defines what input, instance/version,
134
- and configuration to use.
131
+ Runs are provided as [magenta]json[/magenta] objects using the --runs flag.
132
+ Each run defines what input, instance/version, and configuration to use.
135
133
 
136
134
  You can provide runs in three ways:
137
135
  - A single run as a [magenta]json[/magenta] object.
138
- - Multiple runs by repeating the [code]--runs[/code] flag.
139
- - Multiple runs as a [magenta]json[/magenta] array in a single [code]--runs[/code] flag.
136
+ - Multiple runs by repeating the --runs flag.
137
+ - Multiple runs as a [magenta]json[/magenta] array in a single --runs flag.
140
138
 
141
139
  Each run must have the following fields:
142
140
  - [magenta]input_id[/magenta]: ID of the input to use for this run
@@ -146,46 +144,46 @@ def create(
146
144
  - [magenta]instance_id[/magenta] OR [magenta]version_id[/magenta]: Either an instance ID or
147
145
  version ID must be provided (at least one required).
148
146
  - [magenta]option_set[/magenta]: ID of the option set to use (optional).
149
- Make sure to define the option sets using the [code]--option-sets[/code] flag.
147
+ Make sure to define the option sets using the --option-sets flag.
150
148
  - [magenta]input_set_id[/magenta]: ID of the input set (optional).
151
149
  - [magenta]scenario_id[/magenta]: Scenario ID if part of a scenario test (optional).
152
150
  - [magenta]repetition[/magenta]: Repetition number (optional).
153
151
 
154
152
  Object format:
155
- [green]{
153
+ [dim]{
156
154
  "input_id": "meadow-input-a1",
157
155
  "instance_id": "bunny-hopper-v2",
158
156
  "option_set": "speed-optimized",
159
157
  "input_set_id": "spring-gardens"
160
- }[/green]
158
+ }[/dim]
161
159
 
162
160
  [bold][underline]Option Sets[/underline][/bold]
163
161
 
164
162
  Option sets are provided as a [magenta]json[/magenta] object using the
165
- [code]--option-sets[/code] flag. Option sets define named collections of
163
+ --option-sets flag. Option sets define named collections of
166
164
  runtime options that can be referenced by runs.
167
165
 
168
166
  The option sets object is a dictionary where keys are option set IDs and
169
167
  values are dictionaries of string key-value pairs representing the options.
170
168
 
171
169
  Object format:
172
- [green]{
170
+ [dim]{
173
171
  "speed-optimized": {"timeout": "30", "algorithm": "fast"},
174
172
  "quality-focused": {"timeout": "300", "algorithm": "thorough"}
175
- }[/green]
173
+ }[/dim]
176
174
 
177
175
  [bold][underline]Examples[/underline][/bold]
178
176
 
179
177
  - Create a batch experiment with a single run.
180
- $ [green]RUN='{
178
+ $ [dim]RUN='{
181
179
  "input_id": "carrot-patch-a",
182
180
  "instance_id": "warren-planner-v1"
183
181
  }'
184
182
  nextmv cloud batch create --app-id hare-app --batch-experiment-id bunny-hop-test \\
185
- --name "Spring Meadow Routes" --input-set-id spring-gardens --runs "$RUN"[/green]
183
+ --name "Spring Meadow Routes" --input-set-id spring-gardens --runs "$RUN"[/dim]
186
184
 
187
185
  - Create with multiple runs by repeating the flag.
188
- $ [green]RUN1='{
186
+ $ [dim]RUN1='{
189
187
  "input_id": "lettuce-field-1",
190
188
  "instance_id": "hop-optimizer"
191
189
  }'
@@ -195,10 +193,10 @@ def create(
195
193
  }'
196
194
  nextmv cloud batch create --app-id hare-app --batch-experiment-id lettuce-routes \\
197
195
  --name "Lettuce Delivery Optimization" --input-set-id veggie-gardens \\
198
- --runs "$RUN1" --runs "$RUN2"[/green]
196
+ --runs "$RUN1" --runs "$RUN2"[/dim]
199
197
 
200
198
  - Create with multiple runs in a single [magenta]json[/magenta] array.
201
- $ [green]RUNS='[
199
+ $ [dim]RUNS='[
202
200
  {
203
201
  "input_id": "warren-zone-a",
204
202
  "instance_id": "burrow-builder"
@@ -209,28 +207,28 @@ def create(
209
207
  }
210
208
  ]'
211
209
  nextmv cloud batch create --app-id hare-app --batch-experiment-id warren-expansion \\
212
- --name "Warren Construction Plans" --input-set-id burrow-sites --runs "$RUNS"[/green]
210
+ --name "Warren Construction Plans" --input-set-id burrow-sites --runs "$RUNS"[/dim]
213
211
 
214
212
  - Create a batch experiment and wait for it to complete.
215
- $ [green]RUN='{
213
+ $ [dim]RUN='{
216
214
  "input_id": "carrot-harvest",
217
215
  "instance_id": "foraging-route"
218
216
  }'
219
217
  nextmv cloud batch create --app-id hare-app --batch-experiment-id harvest-time \\
220
218
  --name "Autumn Carrot Collection" --input-set-id harvest-season \\
221
- --runs "$RUN" --wait[/green]
219
+ --runs "$RUN" --wait[/dim]
222
220
 
223
221
  - Create a batch experiment and save the results to a file, waiting for completion.
224
- $ [green]RUN='{
222
+ $ [dim]RUN='{
225
223
  "input_id": "predator-zones",
226
224
  "instance_id": "safe-hopper"
227
225
  }'
228
226
  nextmv cloud batch create --app-id hare-app --batch-experiment-id safety-analysis \\
229
227
  --name "Fox Avoidance Routes" --input-set-id danger-zones \\
230
- --runs "$RUN" --output bunny-safety-results.json[/green]
228
+ --runs "$RUN" --output bunny-safety-results.json[/dim]
231
229
 
232
230
  - Create a batch experiment with option sets.
233
- $ [green]RUN1='{
231
+ $ [dim]RUN1='{
234
232
  "input_id": "garden-route-1",
235
233
  "instance_id": "hop-optimizer",
236
234
  "option_set": "fast-hops"
@@ -246,7 +244,7 @@ def create(
246
244
  }'
247
245
  nextmv cloud batch create --app-id hare-app --batch-experiment-id hop-comparison \\
248
246
  --name "Speed vs Safety Analysis" --input-set-id garden-paths \\
249
- --runs "$RUN1" --runs "$RUN2" --option-sets "$OPTION_SETS"[/green]
247
+ --runs "$RUN1" --runs "$RUN2" --option-sets "$OPTION_SETS"[/dim]
250
248
  """
251
249
 
252
250
  cloud_app = build_app(app_id=app_id, profile=profile)
@@ -5,9 +5,9 @@ This module defines the cloud batch delete command for the Nextmv CLI.
5
5
  from typing import Annotated
6
6
 
7
7
  import typer
8
- from rich.prompt import Confirm
9
8
 
10
9
  from nextmv.cli.configuration.config import build_app
10
+ from nextmv.cli.confirm import get_confirmation
11
11
  from nextmv.cli.message import info, success
12
12
  from nextmv.cli.options import AppIDOption, BatchExperimentIDOption, ProfileOption
13
13
 
@@ -33,24 +33,23 @@ def delete(
33
33
  Deletes a Nextmv Cloud batch experiment.
34
34
 
35
35
  This action is permanent and cannot be undone. The batch experiment and all
36
- associated data, including runs, will be deleted. Use the [code]--yes[/code]
36
+ associated data, including runs, will be deleted. Use the --yes
37
37
  flag to skip the confirmation prompt.
38
38
 
39
39
  [bold][underline]Examples[/underline][/bold]
40
40
 
41
41
  - Delete the batch experiment with the ID [magenta]hop-analysis[/magenta] from application
42
42
  [magenta]hare-app[/magenta].
43
- $ [green]nextmv cloud batch delete --app-id hare-app --batch-experiment-id hop-analysis[/green]
43
+ $ [dim]nextmv cloud batch delete --app-id hare-app --batch-experiment-id hop-analysis[/dim]
44
44
 
45
45
  - Delete the batch experiment without confirmation prompt.
46
- $ [green]nextmv cloud batch delete --app-id hare-app --batch-experiment-id carrot-routes --yes[/green]
46
+ $ [dim]nextmv cloud batch delete --app-id hare-app --batch-experiment-id carrot-routes --yes[/dim]
47
47
  """
48
48
 
49
49
  if not yes:
50
- confirm = Confirm.ask(
50
+ confirm = get_confirmation(
51
51
  f"Are you sure you want to delete batch experiment [magenta]{batch_experiment_id}[/magenta] "
52
52
  f"from application [magenta]{app_id}[/magenta]? This action cannot be undone.",
53
- default=False,
54
53
  )
55
54
 
56
55
  if not confirm:
@@ -42,7 +42,7 @@ def get(
42
42
  "--wait",
43
43
  "-w",
44
44
  help="Wait for the batch experiment to complete. Results are printed to [magenta]stdout[/magenta]. "
45
- "Specify output location with [code]--output[/code].",
45
+ "Specify output location with --output.",
46
46
  ),
47
47
  ] = False,
48
48
  profile: ProfileOption = None,
@@ -50,8 +50,8 @@ def get(
50
50
  """
51
51
  Get a Nextmv Cloud batch experiment, including its runs.
52
52
 
53
- Use the [code]--wait[/code] flag to wait for the batch experiment to
54
- complete, polling for results. Using the [code]--output[/code] flag will
53
+ Use the --wait flag to wait for the batch experiment to
54
+ complete, polling for results. Using the --output flag will
55
55
  also activate waiting, and allows you to specify a destination file for the
56
56
  results.
57
57
 
@@ -59,17 +59,17 @@ def get(
59
59
 
60
60
  - Get the batch experiment with ID [magenta]carrot-optimization[/magenta] from application
61
61
  [magenta]hare-app[/magenta].
62
- $ [green]nextmv cloud batch get --app-id hare-app --batch-experiment-id carrot-optimization[/green]
62
+ $ [dim]nextmv cloud batch get --app-id hare-app --batch-experiment-id carrot-optimization[/dim]
63
63
 
64
64
  - Get the batch experiment and wait for it to complete if necessary.
65
- $ [green]nextmv cloud batch get --app-id hare-app --batch-experiment-id bunny-hop-test --wait[/green]
65
+ $ [dim]nextmv cloud batch get --app-id hare-app --batch-experiment-id bunny-hop-test --wait[/dim]
66
66
 
67
67
  - Get the batch experiment and save the results to a file.
68
- $ [green]nextmv cloud batch get --app-id hare-app --batch-experiment-id warren-planning \\
69
- --output results.json[/green]
68
+ $ [dim]nextmv cloud batch get --app-id hare-app --batch-experiment-id warren-planning \\
69
+ --output results.json[/dim]
70
70
 
71
71
  - Get the batch experiment using a specific profile.
72
- $ [green]nextmv cloud batch get --app-id hare-app --batch-experiment-id lettuce-routes --profile prod[/green]
72
+ $ [dim]nextmv cloud batch get --app-id hare-app --batch-experiment-id lettuce-routes --profile prod[/dim]
73
73
  """
74
74
 
75
75
  cloud_app = build_app(app_id=app_id, profile=profile)
@@ -38,13 +38,13 @@ def list(
38
38
  [bold][underline]Examples[/underline][/bold]
39
39
 
40
40
  - List all batch experiments for application [magenta]hare-app[/magenta].
41
- $ [green]nextmv cloud batch list --app-id hare-app[/green]
41
+ $ [dim]nextmv cloud batch list --app-id hare-app[/dim]
42
42
 
43
43
  - List all batch experiments and save to a file.
44
- $ [green]nextmv cloud batch list --app-id hare-app --output experiments.json[/green]
44
+ $ [dim]nextmv cloud batch list --app-id hare-app --output experiments.json[/dim]
45
45
 
46
46
  - List all batch experiments using a specific profile.
47
- $ [green]nextmv cloud batch list --app-id hare-app --profile prod[/green]
47
+ $ [dim]nextmv cloud batch list --app-id hare-app --profile prod[/dim]
48
48
  """
49
49
 
50
50
  cloud_app = build_app(app_id=app_id, profile=profile)
@@ -41,14 +41,14 @@ def metadata(
41
41
 
42
42
  - Get metadata for batch experiment [magenta]bunny-warren-optimization[/magenta] from application
43
43
  [magenta]hare-app[/magenta].
44
- $ [green]nextmv cloud batch metadata --app-id hare-app --batch-experiment-id bunny-warren-optimization[/green]
44
+ $ [dim]nextmv cloud batch metadata --app-id hare-app --batch-experiment-id bunny-warren-optimization[/dim]
45
45
 
46
46
  - Get metadata and save to a file.
47
- $ [green]nextmv cloud batch metadata --app-id hare-app --batch-experiment-id lettuce-delivery \\
48
- --output metadata.json[/green]
47
+ $ [dim]nextmv cloud batch metadata --app-id hare-app --batch-experiment-id lettuce-delivery \\
48
+ --output metadata.json[/dim]
49
49
 
50
50
  - Get metadata using a specific profile.
51
- $ [green]nextmv cloud batch metadata --app-id hare-app --batch-experiment-id hop-schedule --profile prod[/green]
51
+ $ [dim]nextmv cloud batch metadata --app-id hare-app --batch-experiment-id hop-schedule --profile prod[/dim]
52
52
  """
53
53
 
54
54
  cloud_app = build_app(app_id=app_id, profile=profile)
@@ -57,17 +57,17 @@ def update(
57
57
  [bold][underline]Examples[/underline][/bold]
58
58
 
59
59
  - Update the name of a batch experiment.
60
- $ [green]nextmv cloud batch update --app-id hare-app --batch-experiment-id carrot-feast \\
61
- --name "Spring Carrot Harvest"[/green]
60
+ $ [dim]nextmv cloud batch update --app-id hare-app --batch-experiment-id carrot-feast \\
61
+ --name "Spring Carrot Harvest"[/dim]
62
62
 
63
63
  - Update the description of a batch experiment.
64
- $ [green]nextmv cloud batch update --app-id hare-app --batch-experiment-id bunny-hop-routes \\
65
- --description "Optimizing hop paths through the meadow"[/green]
64
+ $ [dim]nextmv cloud batch update --app-id hare-app --batch-experiment-id bunny-hop-routes \\
65
+ --description "Optimizing hop paths through the meadow"[/dim]
66
66
 
67
67
  - Update both name and description and save the result.
68
- $ [green]nextmv cloud batch update --app-id hare-app --batch-experiment-id lettuce-delivery \\
68
+ $ [dim]nextmv cloud batch update --app-id hare-app --batch-experiment-id lettuce-delivery \\
69
69
  --name "Warren Lettuce Express" --description "Fast lettuce delivery to all burrows" \\
70
- --output updated-batch.json[/green]
70
+ --output updated-batch.json[/dim]
71
71
  """
72
72
 
73
73
  cloud_app = build_app(app_id=app_id, profile=profile)
@@ -14,7 +14,7 @@ app.add_typer(upload_app)
14
14
  @app.callback()
15
15
  def callback() -> None:
16
16
  """
17
- Upload data for Nextmv Cloud application runs.
17
+ Upload data for Nextmv Cloud application components.
18
18
 
19
19
  When data is too large (exceeds [magenta]5 MiB[/magenta]), or you are
20
20
  working with the [magenta]multi-file[/magenta] content format, you can use
@@ -45,29 +45,29 @@ def upload(
45
45
  profile: ProfileOption = None,
46
46
  ) -> None:
47
47
  """
48
- Upload data for Nextmv Cloud application runs.
48
+ Upload data for Nextmv Cloud application components.
49
49
 
50
50
  When data is too large, or is not in a text-based content format, you can
51
51
  use this command to upload information for a Nextmv Cloud application. Data
52
52
  is used for starting new runs, tracking runs, performing experiments, and
53
53
  more.
54
54
 
55
- The [code]--upload-url[/code] flag is required to specify the pre-signed
55
+ The --upload-url flag is required to specify the pre-signed
56
56
  upload URL. It can be obtained using the [code]nextmv cloud upload
57
57
  create[/code] command. Use the [magenta].upload_url[/magenta] field from
58
58
  the command output.
59
59
 
60
60
  The data input should be given through [magenta]stdin[/magenta] or the
61
- [code]--input[/code] flag. When using the [code]--input[/code] flag, the
62
- value can be one of the following:
61
+ --input flag. When using the --input flag, the value can be one of the
62
+ following:
63
63
 
64
- - [green]<FILE_PATH>[/green]: path to a [magenta]file[/magenta] containing
64
+ - [yellow]<FILE_PATH>[/yellow]: path to a [magenta]file[/magenta] containing
65
65
  the data. Use with the [magenta]json[/magenta], and
66
66
  [magenta]text[/magenta] content formats.
67
- - [green]<DIR_PATH>[/green]: path to a [magenta]directory[/magenta]
67
+ - [yellow]<DIR_PATH>[/yellow]: path to a [magenta]directory[/magenta]
68
68
  containing data files. Use with the [magenta]multi-file[/magenta]
69
69
  content format.
70
- - [green]<.tar.gz_PATH>[/green]: path to a [magenta].tar.gz[/magenta] file
70
+ - [yellow]<.tar.gz PATH>[/yellow]: path to a [magenta].tar.gz[/magenta] file
71
71
  containing tarred data files. Use with the [magenta]multi-file[/magenta]
72
72
  content format.
73
73
 
@@ -75,30 +75,30 @@ def upload(
75
75
 
76
76
  - Upload data from [magenta]stdin[/magenta] for application
77
77
  [magenta]hare-app[/magenta].
78
- $ [green]echo '{"key": "value"}' | nextmv cloud data upload --app-id hare-app --upload-url <URL>[/green]
78
+ $ [dim]echo '{"key": "value"}' | nextmv cloud data upload --app-id hare-app --upload-url <URL>[/dim]
79
79
 
80
80
  - Upload data from a [magenta]JSON[/magenta] file.
81
- $ [green]nextmv cloud data upload --app-id hare-app --upload-url <URL> --input data.json[/green]
81
+ $ [dim]nextmv cloud data upload --app-id hare-app --upload-url <URL> --input data.json[/dim]
82
82
 
83
83
  - Upload data from a [magenta]text[/magenta] file.
84
- $ [green]nextmv cloud data upload --app-id hare-app --upload-url <URL> --input data.txt[/green]
84
+ $ [dim]nextmv cloud data upload --app-id hare-app --upload-url <URL> --input data.txt[/dim]
85
85
 
86
86
  - Upload [magenta]multi-file[/magenta] data from a directory.
87
- $ [green]nextmv cloud data upload --app-id hare-app --upload-url <URL> --input ./data_directory[/green]
87
+ $ [dim]nextmv cloud data upload --app-id hare-app --upload-url <URL> --input ./data_directory[/dim]
88
88
 
89
89
  - Upload [magenta]multi-file[/magenta] data from a
90
90
  [magenta].tar.gz[/magenta] file.
91
- $ [green]nextmv cloud data upload --app-id hare-app --upload-url <URL> --input data.tar.gz[/green]
91
+ $ [dim]nextmv cloud data upload --app-id hare-app --upload-url <URL> --input data.tar.gz[/dim]
92
92
 
93
93
  - Upload data using a specific profile.
94
- $ [green]nextmv cloud data upload --app-id hare-app --upload-url <URL> --input data.json \\
95
- --profile production[/green]
94
+ $ [dim]nextmv cloud data upload --app-id hare-app --upload-url <URL> --input data.json \\
95
+ --profile production[/dim]
96
96
  """
97
97
 
98
98
  # Validate that input is provided.
99
99
  stdin = sys.stdin.read().strip() if sys.stdin.isatty() is False else None
100
100
  if stdin is None and (input is None or input == ""):
101
- error("Input data must be provided via the [code]--input[/code] flag or [magenta]stdin[/magenta].")
101
+ error("Input data must be provided via the --input flag or [magenta]stdin[/magenta].")
102
102
 
103
103
  cloud_app = build_app(app_id=app_id, profile=profile)
104
104
  data_kwarg = resolve_data_kwarg(
@@ -7,6 +7,7 @@ import typer
7
7
  from nextmv.cli.cloud.ensemble.create import app as create_app
8
8
  from nextmv.cli.cloud.ensemble.delete import app as delete_app
9
9
  from nextmv.cli.cloud.ensemble.get import app as get_app
10
+ from nextmv.cli.cloud.ensemble.list import app as list_app
10
11
  from nextmv.cli.cloud.ensemble.update import app as update_app
11
12
 
12
13
  # Set up subcommand application.
@@ -14,6 +15,7 @@ app = typer.Typer()
14
15
  app.add_typer(create_app)
15
16
  app.add_typer(delete_app)
16
17
  app.add_typer(get_app)
18
+ app.add_typer(list_app)
17
19
  app.add_typer(update_app)
18
20
 
19
21
 
@@ -30,13 +30,12 @@ app = typer.Typer()
30
30
  [bold][underline]Run Groups[/underline][/bold]
31
31
 
32
32
  Run groups are provided as [magenta]json[/magenta] objects using the
33
- [code]--run-groups[/code] flag. Each run group specifies how child runs
34
- are executed.
33
+ --run-groups flag. Each run group specifies how child runs are executed.
35
34
 
36
35
  You can provide run groups in three ways:
37
36
  - A single run group as a [magenta]json[/magenta] object.
38
- - Multiple run groups by repeating the [code]--run-groups[/code] flag.
39
- - Multiple run groups as a [magenta]json[/magenta] array in a single [code]--run-groups[/code] flag.
37
+ - Multiple run groups by repeating the --run-groups flag.
38
+ - Multiple run groups as a [magenta]json[/magenta] array in a single --run-groups flag.
40
39
 
41
40
  Each run group must have the following fields:
42
41
  - [magenta]id[/magenta]: Unique identifier for the run group (required).
@@ -46,23 +45,23 @@ app = typer.Typer()
46
45
  - [magenta]repetitions[/magenta]: Number of times to repeat the run (optional).
47
46
 
48
47
  Object format:
49
- [green]{{
48
+ [dim]{{
50
49
  "id": "rg1",
51
50
  "instance_id": "inst-123",
52
51
  "options": {{"param": "value"}},
53
52
  "repetitions": 5
54
- }}[/green]
53
+ }}[/dim]
55
54
 
56
55
  [bold][underline]Evaluation Rules[/underline][/bold]
57
56
 
58
57
  Evaluation rules are provided as [magenta]json[/magenta] objects using the
59
- [code]--rules[/code] flag. Each rule determines how to evaluate and select
60
- the best result from the child runs.
58
+ --rules flag. Each rule determines how to evaluate and select the best
59
+ result from the child runs.
61
60
 
62
61
  You can provide rules in three ways:
63
62
  - A single rule as a [magenta]json[/magenta] object.
64
- - Multiple rules by repeating the [code]--rules[/code] flag.
65
- - Multiple rules as a [magenta]json[/magenta] array in a single [code]--rules[/code] flag.
63
+ - Multiple rules by repeating the --rules flag.
64
+ - Multiple rules as a [magenta]json[/magenta] array in a single --rules flag.
66
65
 
67
66
  Each rule must have the following fields:
68
67
  - [magenta]id[/magenta]: Unique identifier for the rule (required).
@@ -75,18 +74,18 @@ app = typer.Typer()
75
74
  - [magenta]index[/magenta]: Evaluation order - lower indices evaluated first (required).
76
75
 
77
76
  Object format:
78
- [green]{{
77
+ [dim]{{
79
78
  "id": "rule1",
80
79
  "statistics_path": "$.result.value",
81
80
  "objective": "minimize",
82
81
  "tolerance": {{"value": 0.1, "type": "relative"}},
83
82
  "index": 0
84
- }}[/green]
83
+ }}[/dim]
85
84
 
86
85
  [bold][underline]Examples[/underline][/bold]
87
86
 
88
87
  - Create an ensemble definition with a single run group and rule.
89
- $ [green]RUN_GROUP='{{
88
+ $ [dim]RUN_GROUP='{{
90
89
  "id": "rg1",
91
90
  "instance_id": "inst-123"
92
91
  }}'
@@ -97,10 +96,10 @@ app = typer.Typer()
97
96
  "tolerance": {{"value": 0.1, "type": "relative"}},
98
97
  "index": 0
99
98
  }}'
100
- nextmv cloud ensemble create --app-id hare-app --run-groups "$RUN_GROUP" --rules "$RULE"[/green]
99
+ nextmv cloud ensemble create --app-id hare-app --run-groups "$RUN_GROUP" --rules "$RULE"[/dim]
101
100
 
102
101
  - Create with multiple run groups by repeating the flag.
103
- $ [green]RUN_GROUP_1='{{
102
+ $ [dim]RUN_GROUP_1='{{
104
103
  "id": "rg1",
105
104
  "instance_id": "inst-123"
106
105
  }}'
@@ -117,10 +116,10 @@ app = typer.Typer()
117
116
  "index": 0
118
117
  }}'
119
118
  nextmv cloud ensemble create --app-id hare-app --run-groups "$RUN_GROUP_1" --run-groups "$RUN_GROUP_2" \\
120
- --rules "$RULE"[/green]
119
+ --rules "$RULE"[/dim]
121
120
 
122
121
  - Create with multiple items in a single JSON array.
123
- $ [green]RUN_GROUPS='[
122
+ $ [dim]RUN_GROUPS='[
124
123
  {{"id": "rg1", "instance_id": "inst-123"}},
125
124
  {{"id": "rg2", "instance_id": "inst-456"}}
126
125
  ]'
@@ -131,10 +130,10 @@ app = typer.Typer()
131
130
  "tolerance": {{"value": 0.1, "type": "relative"}},
132
131
  "index": 0
133
132
  }}]'
134
- nextmv cloud ensemble create --app-id hare-app --run-groups "$RUN_GROUPS" --rules "$RULES"[/green]
133
+ nextmv cloud ensemble create --app-id hare-app --run-groups "$RUN_GROUPS" --rules "$RULES"[/dim]
135
134
 
136
135
  - Create with custom ID, name, and description.
137
- $ [green]RUN_GROUP='{{
136
+ $ [dim]RUN_GROUP='{{
138
137
  "id": "rg1",
139
138
  "instance_id": "inst-123"
140
139
  }}'
@@ -148,10 +147,10 @@ app = typer.Typer()
148
147
  nextmv cloud ensemble create --app-id hare-app \\
149
148
  --ensemble-definition-id prod-ensemble --name "Production Ensemble" \\
150
149
  --description "Production ensemble with multiple solvers" \\
151
- --run-groups "$RUN_GROUP" --rules "$RULE"[/green]
150
+ --run-groups "$RUN_GROUP" --rules "$RULE"[/dim]
152
151
 
153
152
  - Create with run group repetitions.
154
- $ [green]RUN_GROUP='{{
153
+ $ [dim]RUN_GROUP='{{
155
154
  "id": "rg1",
156
155
  "instance_id": "inst-123",
157
156
  "repetitions": 5
@@ -163,7 +162,7 @@ app = typer.Typer()
163
162
  "tolerance": {{"value": 0.1, "type": "relative"}},
164
163
  "index": 0
165
164
  }}'
166
- nextmv cloud ensemble create --app-id hare-app --run-groups "$RUN_GROUP" --rules "$RULE"[/green]
165
+ nextmv cloud ensemble create --app-id hare-app --run-groups "$RUN_GROUP" --rules "$RULE"[/dim]
167
166
  """
168
167
  )
169
168
  def create(
@@ -5,9 +5,9 @@ This module defines the cloud ensemble delete command for the Nextmv CLI.
5
5
  from typing import Annotated
6
6
 
7
7
  import typer
8
- from rich.prompt import Confirm
9
8
 
10
9
  from nextmv.cli.configuration.config import build_app
10
+ from nextmv.cli.confirm import get_confirmation
11
11
  from nextmv.cli.message import info, success
12
12
  from nextmv.cli.options import AppIDOption, EnsembleDefinitionIDOption, ProfileOption
13
13
 
@@ -32,24 +32,23 @@ def delete(
32
32
  """
33
33
  Deletes a Nextmv Cloud ensemble definition.
34
34
 
35
- This action is permanent and cannot be undone. Use the [code]--yes[/code]
35
+ This action is permanent and cannot be undone. Use the --yes
36
36
  flag to skip the confirmation prompt.
37
37
 
38
38
  [bold][underline]Examples[/underline][/bold]
39
39
 
40
40
  - Delete the ensemble definition with the ID [magenta]prod-ensemble[/magenta] from application
41
41
  [magenta]hare-app[/magenta].
42
- $ [green]nextmv cloud ensemble delete --app-id hare-app --ensemble-definition-id prod-ensemble[/green]
42
+ $ [dim]nextmv cloud ensemble delete --app-id hare-app --ensemble-definition-id prod-ensemble[/dim]
43
43
 
44
44
  - Delete the ensemble definition without confirmation prompt.
45
- $ [green]nextmv cloud ensemble delete --app-id hare-app --ensemble-definition-id prod-ensemble --yes[/green]
45
+ $ [dim]nextmv cloud ensemble delete --app-id hare-app --ensemble-definition-id prod-ensemble --yes[/dim]
46
46
  """
47
47
 
48
48
  if not yes:
49
- confirm = Confirm.ask(
49
+ confirm = get_confirmation(
50
50
  f"Are you sure you want to delete ensemble definition [magenta]{ensemble_definition_id}[/magenta] "
51
51
  f"from application [magenta]{app_id}[/magenta]? This action cannot be undone.",
52
- default=False,
53
52
  )
54
53
 
55
54
  if not confirm:
@@ -40,13 +40,13 @@ def get(
40
40
 
41
41
  - Get the ensemble definition with the ID [magenta]prod-ensemble[/magenta] from
42
42
  application [magenta]hare-app[/magenta].
43
- $ [green]nextmv cloud ensemble get --app-id hare-app \\
44
- --ensemble-definition-id prod-ensemble[/green]
43
+ $ [dim]nextmv cloud ensemble get --app-id hare-app \\
44
+ --ensemble-definition-id prod-ensemble[/dim]
45
45
 
46
46
  - Get the ensemble definition with the ID [magenta]prod-ensemble[/magenta] and
47
47
  save the information to an [magenta]ensemble.json[/magenta] file.
48
- $ [green]nextmv cloud ensemble get --app-id hare-app \\
49
- --ensemble-definition-id prod-ensemble --output ensemble.json[/green]
48
+ $ [dim]nextmv cloud ensemble get --app-id hare-app \\
49
+ --ensemble-definition-id prod-ensemble --output ensemble.json[/dim]
50
50
  """
51
51
 
52
52
  cloud_app = build_app(app_id=app_id, profile=profile)
@@ -0,0 +1,63 @@
1
+ """
2
+ This module defines the cloud ensemble list command for the Nextmv CLI.
3
+ """
4
+
5
+ import json
6
+ from typing import Annotated
7
+
8
+ import typer
9
+
10
+ from nextmv.cli.configuration.config import build_app
11
+ from nextmv.cli.message import in_progress, print_json, success
12
+ from nextmv.cli.options import AppIDOption, ProfileOption
13
+
14
+ # Set up subcommand application.
15
+ app = typer.Typer()
16
+
17
+
18
+ @app.command()
19
+ def list(
20
+ app_id: AppIDOption,
21
+ output: Annotated[
22
+ str | None,
23
+ typer.Option(
24
+ "--output",
25
+ "-o",
26
+ help="Saves the list of ensemble definitions to this location.",
27
+ metavar="OUTPUT_PATH",
28
+ ),
29
+ ] = None,
30
+ profile: ProfileOption = None,
31
+ ) -> None:
32
+ """
33
+ List all Nextmv Cloud ensemble definitions for an application.
34
+
35
+ This command retrieves all ensemble definitions associated with the specified
36
+ application.
37
+
38
+ [bold][underline]Examples[/underline][/bold]
39
+
40
+ - List all ensemble definitions for application [magenta]hare-app[/magenta].
41
+ $ [dim]nextmv cloud ensemble list --app-id hare-app[/dim]
42
+
43
+ - List all ensemble definitions and save to a file.
44
+ $ [dim]nextmv cloud ensemble list --app-id hare-app --output ensembles.json[/dim]
45
+
46
+ - List all ensemble definitions using a specific profile.
47
+ $ [dim]nextmv cloud ensemble list --app-id hare-app --profile prod[/dim]
48
+ """
49
+
50
+ cloud_app = build_app(app_id=app_id, profile=profile)
51
+ in_progress(msg="Listing ensemble definitions...")
52
+ ensembles = cloud_app.list_ensemble_definitions()
53
+ ensembles_dict = [ensemble.to_dict() for ensemble in ensembles]
54
+
55
+ if output is not None and output != "":
56
+ with open(output, "w") as f:
57
+ json.dump(ensembles_dict, f, indent=2)
58
+
59
+ success(msg=f"Ensemble definitions list saved to [magenta]{output}[/magenta].")
60
+
61
+ return
62
+
63
+ print_json(ensembles_dict)