nextmv 0.40.0__tar.gz → 1.0.0.dev0__tar.gz

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 (210) hide show
  1. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/.gitignore +0 -1
  2. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/PKG-INFO +33 -8
  3. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/README.md +32 -7
  4. nextmv-1.0.0.dev0/nextmv/__about__.py +1 -0
  5. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/__init__.py +2 -0
  6. nextmv-1.0.0.dev0/nextmv/cli/CONTRIBUTING.md +511 -0
  7. nextmv-1.0.0.dev0/nextmv/cli/cloud/__init__.py +45 -0
  8. nextmv-1.0.0.dev0/nextmv/cli/cloud/acceptance/__init__.py +27 -0
  9. nextmv-1.0.0.dev0/nextmv/cli/cloud/acceptance/create.py +393 -0
  10. nextmv-1.0.0.dev0/nextmv/cli/cloud/acceptance/delete.py +68 -0
  11. nextmv-1.0.0.dev0/nextmv/cli/cloud/acceptance/get.py +104 -0
  12. nextmv-1.0.0.dev0/nextmv/cli/cloud/acceptance/list.py +62 -0
  13. nextmv-1.0.0.dev0/nextmv/cli/cloud/acceptance/update.py +95 -0
  14. nextmv-1.0.0.dev0/nextmv/cli/cloud/account/__init__.py +28 -0
  15. nextmv-1.0.0.dev0/nextmv/cli/cloud/account/create.py +83 -0
  16. nextmv-1.0.0.dev0/nextmv/cli/cloud/account/delete.py +60 -0
  17. nextmv-1.0.0.dev0/nextmv/cli/cloud/account/get.py +66 -0
  18. nextmv-1.0.0.dev0/nextmv/cli/cloud/account/update.py +70 -0
  19. nextmv-1.0.0.dev0/nextmv/cli/cloud/app/__init__.py +35 -0
  20. nextmv-1.0.0.dev0/nextmv/cli/cloud/app/create.py +141 -0
  21. nextmv-1.0.0.dev0/nextmv/cli/cloud/app/delete.py +58 -0
  22. nextmv-1.0.0.dev0/nextmv/cli/cloud/app/exists.py +44 -0
  23. nextmv-1.0.0.dev0/nextmv/cli/cloud/app/get.py +66 -0
  24. nextmv-1.0.0.dev0/nextmv/cli/cloud/app/list.py +61 -0
  25. nextmv-1.0.0.dev0/nextmv/cli/cloud/app/push.py +137 -0
  26. nextmv-1.0.0.dev0/nextmv/cli/cloud/app/update.py +124 -0
  27. nextmv-1.0.0.dev0/nextmv/cli/cloud/batch/__init__.py +29 -0
  28. nextmv-1.0.0.dev0/nextmv/cli/cloud/batch/create.py +454 -0
  29. nextmv-1.0.0.dev0/nextmv/cli/cloud/batch/delete.py +68 -0
  30. nextmv-1.0.0.dev0/nextmv/cli/cloud/batch/get.py +104 -0
  31. nextmv-1.0.0.dev0/nextmv/cli/cloud/batch/list.py +63 -0
  32. nextmv-1.0.0.dev0/nextmv/cli/cloud/batch/metadata.py +66 -0
  33. nextmv-1.0.0.dev0/nextmv/cli/cloud/batch/update.py +95 -0
  34. nextmv-1.0.0.dev0/nextmv/cli/cloud/data/__init__.py +26 -0
  35. nextmv-1.0.0.dev0/nextmv/cli/cloud/data/upload.py +162 -0
  36. nextmv-1.0.0.dev0/nextmv/cli/cloud/ensemble/__init__.py +31 -0
  37. nextmv-1.0.0.dev0/nextmv/cli/cloud/ensemble/create.py +414 -0
  38. nextmv-1.0.0.dev0/nextmv/cli/cloud/ensemble/delete.py +67 -0
  39. nextmv-1.0.0.dev0/nextmv/cli/cloud/ensemble/get.py +65 -0
  40. nextmv-1.0.0.dev0/nextmv/cli/cloud/ensemble/update.py +103 -0
  41. nextmv-1.0.0.dev0/nextmv/cli/cloud/input_set/__init__.py +30 -0
  42. nextmv-1.0.0.dev0/nextmv/cli/cloud/input_set/create.py +168 -0
  43. nextmv-1.0.0.dev0/nextmv/cli/cloud/input_set/get.py +63 -0
  44. nextmv-1.0.0.dev0/nextmv/cli/cloud/input_set/list.py +63 -0
  45. nextmv-1.0.0.dev0/nextmv/cli/cloud/input_set/update.py +123 -0
  46. nextmv-1.0.0.dev0/nextmv/cli/cloud/instance/__init__.py +35 -0
  47. nextmv-1.0.0.dev0/nextmv/cli/cloud/instance/create.py +290 -0
  48. nextmv-1.0.0.dev0/nextmv/cli/cloud/instance/delete.py +62 -0
  49. nextmv-1.0.0.dev0/nextmv/cli/cloud/instance/exists.py +39 -0
  50. nextmv-1.0.0.dev0/nextmv/cli/cloud/instance/get.py +62 -0
  51. nextmv-1.0.0.dev0/nextmv/cli/cloud/instance/list.py +60 -0
  52. nextmv-1.0.0.dev0/nextmv/cli/cloud/instance/update.py +216 -0
  53. nextmv-1.0.0.dev0/nextmv/cli/cloud/managed_input/__init__.py +31 -0
  54. nextmv-1.0.0.dev0/nextmv/cli/cloud/managed_input/create.py +146 -0
  55. nextmv-1.0.0.dev0/nextmv/cli/cloud/managed_input/delete.py +65 -0
  56. nextmv-1.0.0.dev0/nextmv/cli/cloud/managed_input/get.py +63 -0
  57. nextmv-1.0.0.dev0/nextmv/cli/cloud/managed_input/list.py +60 -0
  58. nextmv-1.0.0.dev0/nextmv/cli/cloud/managed_input/update.py +97 -0
  59. nextmv-1.0.0.dev0/nextmv/cli/cloud/run/__init__.py +37 -0
  60. nextmv-1.0.0.dev0/nextmv/cli/cloud/run/cancel.py +37 -0
  61. nextmv-1.0.0.dev0/nextmv/cli/cloud/run/create.py +530 -0
  62. nextmv-1.0.0.dev0/nextmv/cli/cloud/run/get.py +199 -0
  63. nextmv-1.0.0.dev0/nextmv/cli/cloud/run/input.py +86 -0
  64. nextmv-1.0.0.dev0/nextmv/cli/cloud/run/list.py +80 -0
  65. nextmv-1.0.0.dev0/nextmv/cli/cloud/run/logs.py +167 -0
  66. nextmv-1.0.0.dev0/nextmv/cli/cloud/run/metadata.py +67 -0
  67. nextmv-1.0.0.dev0/nextmv/cli/cloud/run/track.py +501 -0
  68. nextmv-1.0.0.dev0/nextmv/cli/cloud/scenario/__init__.py +29 -0
  69. nextmv-1.0.0.dev0/nextmv/cli/cloud/scenario/create.py +451 -0
  70. nextmv-1.0.0.dev0/nextmv/cli/cloud/scenario/delete.py +65 -0
  71. nextmv-1.0.0.dev0/nextmv/cli/cloud/scenario/get.py +102 -0
  72. nextmv-1.0.0.dev0/nextmv/cli/cloud/scenario/list.py +63 -0
  73. nextmv-1.0.0.dev0/nextmv/cli/cloud/scenario/metadata.py +67 -0
  74. nextmv-1.0.0.dev0/nextmv/cli/cloud/scenario/update.py +93 -0
  75. nextmv-1.0.0.dev0/nextmv/cli/cloud/secrets/__init__.py +33 -0
  76. nextmv-1.0.0.dev0/nextmv/cli/cloud/secrets/create.py +206 -0
  77. nextmv-1.0.0.dev0/nextmv/cli/cloud/secrets/delete.py +67 -0
  78. nextmv-1.0.0.dev0/nextmv/cli/cloud/secrets/get.py +66 -0
  79. nextmv-1.0.0.dev0/nextmv/cli/cloud/secrets/list.py +60 -0
  80. nextmv-1.0.0.dev0/nextmv/cli/cloud/secrets/update.py +147 -0
  81. nextmv-1.0.0.dev0/nextmv/cli/cloud/upload/__init__.py +22 -0
  82. nextmv-1.0.0.dev0/nextmv/cli/cloud/upload/create.py +39 -0
  83. nextmv-1.0.0.dev0/nextmv/cli/cloud/version/__init__.py +33 -0
  84. nextmv-1.0.0.dev0/nextmv/cli/cloud/version/create.py +97 -0
  85. nextmv-1.0.0.dev0/nextmv/cli/cloud/version/delete.py +62 -0
  86. nextmv-1.0.0.dev0/nextmv/cli/cloud/version/exists.py +39 -0
  87. nextmv-1.0.0.dev0/nextmv/cli/cloud/version/get.py +62 -0
  88. nextmv-1.0.0.dev0/nextmv/cli/cloud/version/list.py +60 -0
  89. nextmv-1.0.0.dev0/nextmv/cli/cloud/version/update.py +92 -0
  90. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/cli/community/clone.py +3 -3
  91. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/cli/community/list.py +1 -1
  92. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/cli/configuration/config.py +68 -4
  93. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/cli/configuration/create.py +14 -15
  94. nextmv-1.0.0.dev0/nextmv/cli/configuration/delete.py +67 -0
  95. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/cli/configuration/list.py +1 -1
  96. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/cli/main.py +58 -16
  97. nextmv-1.0.0.dev0/nextmv/cli/message.py +153 -0
  98. nextmv-1.0.0.dev0/nextmv/cli/options.py +192 -0
  99. nextmv-1.0.0.dev0/nextmv/cli/version.py +38 -0
  100. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/cloud/__init__.py +4 -1
  101. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/cloud/acceptance_test.py +19 -18
  102. nextmv-1.0.0.dev0/nextmv/cloud/account.py +457 -0
  103. nextmv-1.0.0.dev0/nextmv/cloud/application/__init__.py +955 -0
  104. nextmv-1.0.0.dev0/nextmv/cloud/application/_acceptance.py +419 -0
  105. nextmv-1.0.0.dev0/nextmv/cloud/application/_batch_scenario.py +860 -0
  106. nextmv-1.0.0.dev0/nextmv/cloud/application/_ensemble.py +251 -0
  107. nextmv-1.0.0.dev0/nextmv/cloud/application/_input_set.py +227 -0
  108. nextmv-1.0.0.dev0/nextmv/cloud/application/_instance.py +289 -0
  109. nextmv-1.0.0.dev0/nextmv/cloud/application/_managed_input.py +227 -0
  110. nextmv-1.0.0.dev0/nextmv/cloud/application/_run.py +1393 -0
  111. nextmv-1.0.0.dev0/nextmv/cloud/application/_secrets.py +294 -0
  112. nextmv-1.0.0.dev0/nextmv/cloud/application/_utils.py +54 -0
  113. nextmv-1.0.0.dev0/nextmv/cloud/application/_version.py +303 -0
  114. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/cloud/batch_experiment.py +3 -1
  115. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/cloud/instance.py +11 -1
  116. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/cloud/integration.py +1 -1
  117. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/cloud/package.py +50 -9
  118. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/input.py +20 -36
  119. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/local/application.py +3 -15
  120. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/polling.py +54 -16
  121. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/run.py +83 -27
  122. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/pyproject.toml +1 -1
  123. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/cli/test_community.py +1 -1
  124. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/cli/test_configuration.py +11 -11
  125. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/test_input.py +0 -47
  126. nextmv-0.40.0/nextmv/__about__.py +0 -1
  127. nextmv-0.40.0/nextmv/cli/configuration/delete.py +0 -55
  128. nextmv-0.40.0/nextmv/cli/error.py +0 -22
  129. nextmv-0.40.0/nextmv/cli/options.py +0 -24
  130. nextmv-0.40.0/nextmv/cli/version.py +0 -19
  131. nextmv-0.40.0/nextmv/cloud/account.py +0 -213
  132. nextmv-0.40.0/nextmv/cloud/application.py +0 -4204
  133. nextmv-0.40.0/tests/scripts/__init__.py +0 -0
  134. nextmv-0.40.0/tests/test_entrypoint/__init__.py +0 -0
  135. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/LICENSE +0 -0
  136. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/__entrypoint__.py +0 -0
  137. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/_serialization.py +0 -0
  138. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/base_model.py +0 -0
  139. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/cli/__init__.py +0 -0
  140. /nextmv-0.40.0/nextmv/cli/community/community.py → /nextmv-1.0.0.dev0/nextmv/cli/community/__init__.py +0 -0
  141. /nextmv-0.40.0/nextmv/cli/configuration/configuration.py → /nextmv-1.0.0.dev0/nextmv/cli/configuration/__init__.py +0 -0
  142. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/cloud/assets.py +0 -0
  143. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/cloud/client.py +0 -0
  144. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/cloud/ensemble.py +0 -0
  145. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/cloud/input_set.py +0 -0
  146. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/cloud/scenario.py +0 -0
  147. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/cloud/secrets.py +0 -0
  148. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/cloud/url.py +0 -0
  149. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/cloud/version.py +0 -0
  150. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/default_app/.gitignore +0 -0
  151. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/default_app/README.md +0 -0
  152. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/default_app/app.yaml +0 -0
  153. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/default_app/input.json +0 -0
  154. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/default_app/main.py +0 -0
  155. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/default_app/requirements.txt +0 -0
  156. {nextmv-0.40.0/nextmv/cli/community → nextmv-1.0.0.dev0/nextmv/default_app/src}/__init__.py +0 -0
  157. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/default_app/src/visuals.py +0 -0
  158. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/deprecated.py +0 -0
  159. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/local/__init__.py +0 -0
  160. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/local/executor.py +0 -0
  161. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/local/geojson_handler.py +0 -0
  162. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/local/local.py +0 -0
  163. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/local/plotly_handler.py +0 -0
  164. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/local/runner.py +0 -0
  165. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/logger.py +0 -0
  166. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/manifest.py +0 -0
  167. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/model.py +0 -0
  168. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/options.py +0 -0
  169. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/output.py +0 -0
  170. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/safe.py +0 -0
  171. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/nextmv/status.py +0 -0
  172. {nextmv-0.40.0/nextmv/cli/configuration → nextmv-1.0.0.dev0/tests}/__init__.py +0 -0
  173. {nextmv-0.40.0/nextmv/default_app/src → nextmv-1.0.0.dev0/tests/cli}/__init__.py +0 -0
  174. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/cli/test_main.py +0 -0
  175. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/cli/test_version.py +0 -0
  176. {nextmv-0.40.0/tests → nextmv-1.0.0.dev0/tests/cloud}/__init__.py +0 -0
  177. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/cloud/app.yaml +0 -0
  178. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/cloud/test_client.py +0 -0
  179. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/cloud/test_instance.py +0 -0
  180. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/cloud/test_package.py +0 -0
  181. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/cloud/test_scenario.py +0 -0
  182. {nextmv-0.40.0/tests/cli → nextmv-1.0.0.dev0/tests/local}/__init__.py +0 -0
  183. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/local/test_application.py +0 -0
  184. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/local/test_executor.py +0 -0
  185. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/local/test_runner.py +0 -0
  186. {nextmv-0.40.0/tests/cloud → nextmv-1.0.0.dev0/tests/scripts}/__init__.py +0 -0
  187. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/scripts/options1.py +0 -0
  188. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/scripts/options2.py +0 -0
  189. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/scripts/options3.py +0 -0
  190. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/scripts/options4.py +0 -0
  191. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/scripts/options5.py +0 -0
  192. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/scripts/options6.py +0 -0
  193. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/scripts/options7.py +0 -0
  194. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/scripts/options_deprecated.py +0 -0
  195. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/test_base_model.py +0 -0
  196. {nextmv-0.40.0/tests/local → nextmv-1.0.0.dev0/tests/test_entrypoint}/__init__.py +0 -0
  197. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/test_entrypoint/test_entrypoint.py +0 -0
  198. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/test_inputs/test_data.csv +0 -0
  199. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/test_inputs/test_data.json +0 -0
  200. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/test_inputs/test_data.txt +0 -0
  201. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/test_logger.py +0 -0
  202. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/test_manifest.py +0 -0
  203. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/test_model.py +0 -0
  204. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/test_options.py +0 -0
  205. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/test_output.py +0 -0
  206. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/test_polling.py +0 -0
  207. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/test_run.py +0 -0
  208. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/test_safe.py +0 -0
  209. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/test_serialization.py +0 -0
  210. {nextmv-0.40.0 → nextmv-1.0.0.dev0}/tests/test_version.py +0 -0
@@ -62,7 +62,6 @@ db.sqlite3
62
62
  db.sqlite3-journal
63
63
 
64
64
  # Flask stuff:
65
- instance/
66
65
  .webassets-cache
67
66
 
68
67
  # Scrapy stuff:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nextmv
3
- Version: 0.40.0
3
+ Version: 1.0.0.dev0
4
4
  Summary: The all-purpose Python SDK for Nextmv
5
5
  Project-URL: Homepage, https://www.nextmv.io
6
6
  Project-URL: Documentation, https://nextmv-py.docs.nextmv.io/en/latest/nextmv/
@@ -267,20 +267,45 @@ Description-Content-Type: text/markdown
267
267
 
268
268
  Welcome to `nextmv`, the general Python SDK for the Nextmv Platform.
269
269
 
270
- 📖 To learn more about the `nextmv`, visit the [docs][docs].
270
+ 📖 To learn more about `nextmv`, visit the [docs][docs].
271
271
 
272
272
  ## Installation
273
273
 
274
- Requires Python `>=3.10`. Install using `pip`:
274
+ Requires Python `>=3.10`. Install using the Python package manager of your
275
+ choice:
275
276
 
276
- ```bash
277
- pip install nextmv
278
- ```
277
+ - `pip`
278
+
279
+ ```bash
280
+ pip install nextmv
281
+ ```
282
+
283
+ - `pipx`
284
+
285
+ ```bash
286
+ pipx install nextmv
287
+ ```
279
288
 
280
- Install all optional dependencies (recommended):
289
+ - `uv`
290
+
291
+ ```bash
292
+ uv tool install nextmv
293
+ ```
294
+
295
+ Install all optional dependencies (recommended) by specifying `"nextmv[all]"`
296
+ instead of just `"nextmv"`.
297
+
298
+ ## CLI
299
+
300
+ The Nextmv CLI is installed automatically with the SDK. To verify installation,
301
+ run:
281
302
 
282
303
  ```bash
283
- pip install "nextmv[all]"
304
+ nextmv --help
284
305
  ```
285
306
 
307
+ If you are contributing to the CLI, please make sure you read the [CLI
308
+ Contributing Guide][cli-contributing].
309
+
286
310
  [docs]: https://nextmv-py.docs.nextmv.io/en/latest/nextmv/
311
+ [cli-contributing]: nextmv/cli/CONTRIBUTING.md
@@ -21,20 +21,45 @@
21
21
 
22
22
  Welcome to `nextmv`, the general Python SDK for the Nextmv Platform.
23
23
 
24
- 📖 To learn more about the `nextmv`, visit the [docs][docs].
24
+ 📖 To learn more about `nextmv`, visit the [docs][docs].
25
25
 
26
26
  ## Installation
27
27
 
28
- Requires Python `>=3.10`. Install using `pip`:
28
+ Requires Python `>=3.10`. Install using the Python package manager of your
29
+ choice:
29
30
 
30
- ```bash
31
- pip install nextmv
32
- ```
31
+ - `pip`
32
+
33
+ ```bash
34
+ pip install nextmv
35
+ ```
36
+
37
+ - `pipx`
38
+
39
+ ```bash
40
+ pipx install nextmv
41
+ ```
33
42
 
34
- Install all optional dependencies (recommended):
43
+ - `uv`
44
+
45
+ ```bash
46
+ uv tool install nextmv
47
+ ```
48
+
49
+ Install all optional dependencies (recommended) by specifying `"nextmv[all]"`
50
+ instead of just `"nextmv"`.
51
+
52
+ ## CLI
53
+
54
+ The Nextmv CLI is installed automatically with the SDK. To verify installation,
55
+ run:
35
56
 
36
57
  ```bash
37
- pip install "nextmv[all]"
58
+ nextmv --help
38
59
  ```
39
60
 
61
+ If you are contributing to the CLI, please make sure you read the [CLI
62
+ Contributing Guide][cli-contributing].
63
+
40
64
  [docs]: https://nextmv-py.docs.nextmv.io/en/latest/nextmv/
65
+ [cli-contributing]: nextmv/cli/CONTRIBUTING.md
@@ -0,0 +1 @@
1
+ __version__ = "v1.0.0.dev0"
@@ -53,6 +53,7 @@ from .output import write as write
53
53
  from .output import write_local as write_local
54
54
  from .polling import DEFAULT_POLLING_OPTIONS as DEFAULT_POLLING_OPTIONS
55
55
  from .polling import PollingOptions as PollingOptions
56
+ from .polling import default_polling_options as default_polling_options
56
57
  from .polling import poll as poll
57
58
  from .run import ErrorLog as ErrorLog
58
59
  from .run import ExternalRunResult as ExternalRunResult
@@ -72,6 +73,7 @@ from .run import RunType as RunType
72
73
  from .run import RunTypeConfiguration as RunTypeConfiguration
73
74
  from .run import StatisticsIndicator as StatisticsIndicator
74
75
  from .run import SyncedRun as SyncedRun
76
+ from .run import TimestampedRunLog as TimestampedRunLog
75
77
  from .run import TrackedRun as TrackedRun
76
78
  from .run import TrackedRunStatus as TrackedRunStatus
77
79
  from .run import run_duration as run_duration
@@ -0,0 +1,511 @@
1
+ # Contributing to Nextmv CLI
2
+
3
+ Hello dear contributor. Thank you for helping out with the CLI 😎. Here are a
4
+ few style guidelines to help all of us maintain a high-quality tool, that feels
5
+ unified and consistent. You are required to read and understand these
6
+ guidelines before submitting a pull request.
7
+
8
+ The Nextmv CLI is built using [Typer][typer]. If you don't know Typer, we
9
+ _strongly encourage_ you to read through the [Typer Learn][typer-learn]
10
+ section to understand what is possible with the library. Even if you decide not
11
+ to run the example commands, you should spend 1 - 2 hours reading through the
12
+ material to get a good understanding of how Typer works.
13
+
14
+ We are following Typer's recommendations and using [Rich][rich] for formatting.
15
+ We also _strongly encourage_ you to read though Rich's documentation, spending
16
+ 30 minutes to an hour familiarizing yourself with the library. Quoting directly
17
+ from the Typer docs:
18
+
19
+ > If you are wondering what tool should be used for what, Typer is useful for
20
+ > structuring the command line application, with options, arguments,
21
+ > subcommands, data validation, etc.
22
+ >
23
+ > In general, Typer tends to be the entry point to your program, taking the
24
+ > first input from the user.
25
+ >
26
+ > Rich is useful for the parts that need to display information. Showing
27
+ > beautiful content on the screen.
28
+ >
29
+ > The best results for your command line application would be achieved
30
+ > combining both Typer and Rich.
31
+
32
+ ## Command structure
33
+
34
+ The logic for command tree organization is based on:
35
+
36
+ > Domain > Entity > Action
37
+
38
+ Where:
39
+
40
+ - Domain separates `cloud` from `local`. If there is no domain, the command
41
+ belongs to the root command tree.
42
+ - Entity refers to resources like `run`, `batch-experiment`,
43
+ `secrets-collection`, etc.
44
+ - Action details what can be done on the entity: `create`, `get`, `delete`,
45
+ `list`, etc.
46
+ - Sometimes, it is not practical to follow this logic. Consider the `nextmv
47
+ cloud run` command tree. The available subcommands are:
48
+
49
+ - cancel: Cancel a queued/running Nextmv Cloud application run.
50
+ - create: Create a new Nextmv Cloud application run.
51
+ - get: Get the result (output) of a Nextmv Cloud application run.
52
+ - input: Get the input of a Nextmv Cloud application run.
53
+ - list: Get the list of runs for a Nextmv Cloud application.
54
+ - logs: Get the logs of a Nextmv Cloud application run.
55
+ - metadata: Get the metadata of a Nextmv Cloud application run.
56
+ - track: Track an external run as a Nextmv Cloud application run.
57
+
58
+ Strictly speaking, `input`, `logs`, and `metadata` are not actions. To avoid
59
+ defining a `nextmv cloud run input get` command, which starts getting
60
+ convoluted, we decided to keep these commands as-is. On the other hand, if
61
+ you have the need to define commands like `nextmv cloud run input-update`, or
62
+ `nextmv cloud run input-delete`, then it is better to define a `nextmv cloud run
63
+ input` command tree, with `get`, `update`, and `delete` subcommands.
64
+
65
+ - If possible, use single words for command trees and commands.
66
+ - Use the best judgement when deciding how to structure commands. If you
67
+ believe a different structure makes more sense, feel free to propose it in
68
+ your pull request, explaining the reasoning behind it.
69
+
70
+ ## File organization
71
+
72
+ Follow these guidelines when organizing files and directories for commands:
73
+
74
+ - Directories and files should be named following the command names. For
75
+ example, the `cloud` directory has the `cloud` command tree, and the
76
+ `cloud/app/create.py` file contains the `nextmv cloud app create` command.
77
+ - Place commands in their own Python files. Take the `community` dir, for
78
+ example. The `clone.py` file hosts the `nextmv community clone` command and
79
+ the `list.py` file has the `nextmv community list` command.
80
+ - Place command trees in their own directories. The main command of the command
81
+ tree should live in the `__init__.py` file in the directory. Consider the
82
+ `cloud/app` directory. The `__init__.py` file has the following code, which
83
+ sets up the `nextmv cloud app` command tree and adds seven subcommands to
84
+ it.
85
+
86
+ ```python
87
+ import typer
88
+
89
+ from nextmv.cli.cloud.app.create import app as create_app
90
+ from nextmv.cli.cloud.app.delete import app as delete_app
91
+ from nextmv.cli.cloud.app.exists import app as exists_app
92
+ from nextmv.cli.cloud.app.get import app as get_app
93
+ from nextmv.cli.cloud.app.list import app as list_app
94
+ from nextmv.cli.cloud.app.push import app as push_app
95
+ from nextmv.cli.cloud.app.update import app as update_app
96
+
97
+ # Set up subcommand application.
98
+ app = typer.Typer()
99
+ app.add_typer(create_app)
100
+ app.add_typer(delete_app)
101
+ app.add_typer(exists_app)
102
+ app.add_typer(get_app)
103
+ app.add_typer(list_app)
104
+ app.add_typer(push_app)
105
+ app.add_typer(update_app)
106
+
107
+
108
+ @app.callback()
109
+ def callback() -> None:
110
+ """
111
+ Create, manage, and push Nextmv Cloud applications.
112
+ """
113
+ pass
114
+ ```
115
+
116
+ Each of the commands should be in their own file in the same directory, e.g.
117
+ `create.py`, `delete.py`, etc.
118
+
119
+ - Use the same principle of placing command tree definitions in an
120
+ `__init__.py` file for subcommand trees as well. Consider the `cloud`
121
+ directory. It has an `__init__.py` file and subdirectories. The `__init__.py`
122
+ file has the following code, which sets up the `nextmv cloud` command tree
123
+ and adds several subcommand trees to it.
124
+
125
+ ```python
126
+ import typer
127
+
128
+ from nextmv.cli.cloud.app import app as app_app
129
+ from nextmv.cli.cloud.run import app as run_app
130
+
131
+ # Set up subcommand application.
132
+ app = typer.Typer()
133
+ app.add_typer(app_app, name="app")
134
+ app.add_typer(run_app, name="run")
135
+
136
+
137
+ @app.callback()
138
+ def callback() -> None:
139
+ """
140
+ Interact with Nextmv Cloud, a platform for deploying and managing models.
141
+ """
142
+ pass
143
+ ```
144
+
145
+ ## Printing
146
+
147
+ When information to the user, i.e., printing to the console, follow these
148
+ guidelines:
149
+
150
+ - Unless otherwise necessary, always print and log to `stderr`. This ensures
151
+ that the CLI's output can be piped and redirected without issues.
152
+ - We embrace the use of emojis. They make the CLI friendlier and more
153
+ approachable.
154
+ - The `message.py` file contains helper functions for printing messages, like:
155
+ - `error`: prints an error and raises an exception.
156
+ - `success`: prints a success message.
157
+ - `warning`: prints a warning message.
158
+ - `in_progress`: prints an in-progress message.
159
+ - `info`: prints an informational message. You can give it an emoji for the
160
+ message. The other commands have fixed emojis.
161
+ - For printing `JSON` information, use the `print_json` function in the
162
+ `messages.py` file to print JSON output. This ensures consistent formatting
163
+ across the CLI.
164
+ - Emojis should be formatted according to [Rich's emoji guide][rich-emoji].
165
+ They are strings enclosed in colons, e.g. `:rocket:`, `:boom:`,
166
+ `:hourglass_flowing_sand:`, etc.
167
+ - When using the `success` function, include the variable or entity that was
168
+ affected, formatted with `[magenta]`:
169
+
170
+ ```python
171
+ success(f"Application [magenta]{app_id}[/magenta] deleted successfully.")
172
+ ```
173
+
174
+ ## Confirmation prompts
175
+
176
+ For destructive actions (like deletions), use `rich.prompt.Confirm.ask()` to
177
+ ask for user confirmation before proceeding. Follow these guidelines:
178
+
179
+ - The confirmation message should use `[magenta]` for the variable being
180
+ affected.
181
+ - Set `default=False` for safety, so the user must explicitly confirm.
182
+ - Provide a `--yes` / `-y` flag to skip the confirmation prompt, useful for
183
+ non-interactive sessions.
184
+ - If the user declines, call `info()` with the `:bulb:` emoji and return early.
185
+
186
+ Consider the `nextmv cloud app delete` command:
187
+
188
+ ```python
189
+ if not yes:
190
+ confirm = Confirm.ask(
191
+ f"Are you sure you want to delete application [magenta]{app_id}[/magenta]? This action cannot be undone",
192
+ default=False,
193
+ )
194
+
195
+ if not confirm:
196
+ info(msg=f"Application [magenta]{app_id}[/magenta] will not be deleted.", emoji=":bulb:")
197
+ return
198
+ ```
199
+
200
+ ## Formatting
201
+
202
+ Use these Rich markup guidelines when formatting help text and messages.
203
+
204
+ - When talking about a command, or a command option, use the `[code]` `[/code]`
205
+ tags. Take this example from the help menu of the `cloud/app/delete.py` file.
206
+ In the command help, when referring to the `--yes` option, we use
207
+ `[code]--yes[/code]` to format it as code.
208
+
209
+ ```python
210
+ @app.command()
211
+ def delete(
212
+ app_id: AppIDOption,
213
+ yes: Annotated[
214
+ bool,
215
+ typer.Option(
216
+ "--yes",
217
+ "-y",
218
+ help="Agree to deletion confirmation prompt. Useful for non-interactive sessions.",
219
+ ),
220
+ ] = False,
221
+ profile: ProfileOption = None,
222
+ ) -> None:
223
+ """
224
+ Deletes a Nextmv Cloud application.
225
+
226
+ This action is permanent and cannot be undone. Use the [code]--yes[/code]
227
+ flag to skip the confirmation prompt.
228
+
229
+ [bold][underline]Examples[/underline][/bold]
230
+
231
+ - Delete the application with the ID [magenta]hare-app[/magenta].
232
+ $ [green]nextmv cloud app delete --app-id hare-app[/green]
233
+
234
+ - Delete the application with the ID [magenta]hare-app[/magenta] without confirmation prompt.
235
+ $ [green]nextmv cloud app delete --app-id hare-app --yes[/green]
236
+ """
237
+ ```
238
+
239
+ - When talking about a variable (like a filepath, value of an option, a string,
240
+ etc.), use the `[magenta]` `[/magenta]` tags. Using the same example as
241
+ above, when referring to the application ID `hare-app`, we use
242
+ `[magenta]hare-app[/magenta]` to format it as a variable. Another example is
243
+ when providing error messages that include values:
244
+
245
+ ```python
246
+ error(f"Input path [magenta]{input}[/magenta] does not exist.")
247
+ ```
248
+
249
+ - Links to URLs should be formatted using the `[link=URL_LINK][bold]
250
+ [/bold][/link]` tags. Consider the main help message of the `nextmv
251
+ community` command, in the `community/__init__.py` file:
252
+
253
+ ```python
254
+ @app.callback()
255
+ def callback() -> None:
256
+ """
257
+ Interact with community apps, which are pre-built decision models.
258
+
259
+ Community apps are maintained in the following GitHub repository:
260
+ [link=https://github.com/nextmv-io/community-apps][bold]nextmv-io/community-apps[/bold][/link].
261
+ """
262
+ pass
263
+ ```
264
+
265
+ The link provided is <https://github.com/nextmv-io/community-apps>, and it will
266
+ be applied to the text `nextmv-io/community-apps`.
267
+
268
+ - Colors that can be used for highlighting (we limit colors to keep coloring consistent):
269
+ - `[magenta]`: variable, literals, etc. - mainly short technical things (see above).
270
+ - `[green]`: commands, etc. - longer technical things, or, as a type-contrast to magenta.
271
+ - `[yellow]`: emphasis, highlight of special items, etc. (use sparingly only).
272
+
273
+ ## Command documentation
274
+
275
+ Every command should have good-enough documentation that guides the user on how
276
+ to use it.
277
+
278
+ - Document every command using Python docstrings.
279
+ - Document every option and argument using the `help` parameter of the
280
+ `typer.Option` functions.
281
+ - Option documentation should be short and to the point. Avoid long
282
+ explanations. If necessary, you can add more detailed information in the
283
+ command's help.
284
+ - The help of the command should be structured as follows:
285
+ - A short, one-line description of what the command does.
286
+ - A blank line.
287
+ - A more detailed description of what the command does. This can be multiple
288
+ paragraphs. Only add this section if necessary.
289
+ - A blank line.
290
+ - An Examples section, with one or more examples of how to use the command.
291
+ Each example should have a short description of what it does, followed by
292
+ the command itself. More on example formatting below.
293
+ - Consider the `nextmv cloud app get` command, under the `cloud/app/get.py` file:
294
+
295
+ ```python
296
+ @app.command()
297
+ def get(
298
+ app_id: AppIDOption,
299
+ output: Annotated[
300
+ str | None,
301
+ typer.Option(
302
+ "--output",
303
+ "-o",
304
+ help="Saves the app information to this location.",
305
+ metavar="OUTPUT_PATH",
306
+ ),
307
+ ] = None,
308
+ profile: ProfileOption = None,
309
+ ) -> None:
310
+ """
311
+ Get a Nextmv Cloud application.
312
+
313
+ This command is useful to get the attributes of an existing Nextmv Cloud
314
+ application by its ID.
315
+
316
+ [bold][underline]Examples[/underline][/bold]
317
+
318
+ - Get the application with the ID [magenta]hare-app[/magenta].
319
+ $ [green]nextmv cloud app get --app-id hare-app[/green]
320
+
321
+ - Get the application with the ID [magenta]hare-app[/magenta] and save the information to an
322
+ [magenta]app.json[/magenta] file.
323
+ $ [green]nextmv cloud app get --app-id hare-app --output app.json[/green]
324
+ """
325
+
326
+ client = build_client(profile)
327
+ info(msg="Getting application...", emoji=":hourglass_flowing_sand:")
328
+
329
+ cloud_app = Application.get(
330
+ client=client,
331
+ id=app_id,
332
+ )
333
+ cloud_app_dict = cloud_app.to_dict()
334
+
335
+ if output is not None and output != "":
336
+ with open(output, "w") as f:
337
+ json.dump(cloud_app_dict, f, indent=2)
338
+
339
+ success(msg=f"Application information saved to [magenta]{output}[/magenta].")
340
+
341
+ return
342
+
343
+ print_json(cloud_app_dict)
344
+ ```
345
+
346
+ - The short description is: `Get a Nextmv Cloud application.`
347
+ - The detailed description is:
348
+
349
+ ```text
350
+ This command is useful to get the attributes of an existing Nextmv Cloud
351
+ application by its ID.
352
+ ```
353
+
354
+ - The examples section is fenced with the `[bold][underline]
355
+ [/underline][/bold]` tags.
356
+
357
+ - Each example is listed as a bullet, using a hyphen (`-`).
358
+ - Each example has a short description, followed by the command itself in a
359
+ new line, with 4 spaces of indentation in comparison to where the hyphen is.
360
+ - The command itself should be formatted using the `[green]` `[/green]` tags.
361
+ - The command should start with a dollar sign (`$`), followed by a space, and
362
+ then the actual command.
363
+ - When an example command is too long, use a double backslash (`\\`) for line
364
+ continuation. It gets rendered as a single backslash. The next line should
365
+ have 4 additional spaces of indentation (8 spaces total from the hyphen):
366
+
367
+ ```text
368
+ - Create an application with an ID and description.
369
+ $ [green]nextmv cloud app create --name "Hare App" --app-id hare-app \\
370
+ --description "An application for routing hares"[/green]
371
+ ```
372
+
373
+ ## Command options
374
+
375
+ Consider the following guideline when declaring command options:
376
+
377
+ - We _only_ use command options, we _do not_ use command arguments.
378
+ - Use the `Annotated` type hint from the `typing_extensions` module to declare
379
+ options. Consider the `name` option from the `nextmv cloud app create`
380
+ command hosted in the `cloud/app/create.py` file:
381
+
382
+ ```python
383
+ name: Annotated[
384
+ str,
385
+ typer.Option(
386
+ "--name",
387
+ "-n",
388
+ help="A name for the application.",
389
+ metavar="NAME",
390
+ ),
391
+ ],
392
+ ```
393
+
394
+ The type of the option is `str`, and we use `typer.Option` to declare the
395
+ option's properties.
396
+
397
+ - If possible, provide both a long and short version of the option. In the example
398
+ above, the long version is `--name` and the short version is `-n`.
399
+ - Always provide a `help` parameter that describes what the option does. Avoid
400
+ long-winded explanations here, keep it short and to the point. If you need to
401
+ provide more context about using the option, add that information to the
402
+ command's help docstring.
403
+ - For `str` options, always provide a `metavar` parameter for describing the
404
+ expected value. In the example above, the `metavar` is `NAME`, indicating
405
+ that the option expects a name string.
406
+ - _Optional_ options are declared using the `| None` type hint and normally
407
+ have a default value of `None`. Consider the `default_instance_id` option of
408
+ the same command:
409
+
410
+ ```python
411
+ default_instance_id: Annotated[
412
+ str | None,
413
+ typer.Option(
414
+ "--default-instance-id",
415
+ "-i",
416
+ help="An optional default instance ID for the application.",
417
+ metavar="DEFAULT_INSTANCE_ID",
418
+ ),
419
+ ] = None,
420
+ ```
421
+
422
+ The type hint is `str | None`, and the default value is `None`.
423
+
424
+ - For `bool` options, always provide at least the long name, to avoid the
425
+ auto-populated `--no-...` version of the option, given by Typer.
426
+ - `bool` options should have a default value of either `True` or `False`.
427
+ - Use the `rich_help_panel` to organize commands that have a large number of
428
+ options. Consider the `input` option of the `nextmv cloud run create`
429
+ command, hosted in the `cloud/run/create.py` file:
430
+
431
+ ```python
432
+ input: Annotated[
433
+ str | None,
434
+ typer.Option(
435
+ "--input",
436
+ "-i",
437
+ help="The input path to use. File or directory depending on content format. "
438
+ "Uses [magenta]stdin[/magenta] if not defined.",
439
+ metavar="INPUT_PATH",
440
+ rich_help_panel="Input control",
441
+ ),
442
+ ] = None,
443
+ ```
444
+
445
+ The `rich_help_panel` parameter is set to `Input control`, which groups
446
+ this option under the `Input control` panel in the command's help message.
447
+
448
+ - When an option can be set via an environment variable, use the `envvar`
449
+ parameter. Environment variable names should follow the `NEXTMV_<OPTION_NAME>`
450
+ convention, e.g. `NEXTMV_PROFILE`, `NEXTMV_API_KEY`, `NEXTMV_APP_ID`,
451
+ `NEXTMV_RUN_ID`.
452
+ - Place widely-used options in the `options.py` file, and import them into commands
453
+ that need them. Consider the `profile` option, which is used
454
+ in many `nextmv cloud` commands. It is defined in the `options.py` file:
455
+
456
+ ```python
457
+ # profile option - can be used in any command to specify which profile to use.
458
+ # Define it as follows in commands or callbacks, as necessary:
459
+ # profile: ProfileOption = None
460
+ ProfileOption = Annotated[
461
+ str | None,
462
+ typer.Option(
463
+ "--profile",
464
+ "-p",
465
+ help="Profile to use for this action. Use [code]nextmv configuration[/code] to manage profiles.",
466
+ envvar="NEXTMV_PROFILE",
467
+ metavar="PROFILE_NAME",
468
+ ),
469
+ ]
470
+ ```
471
+
472
+ Then, in commands that need these options, simply import them and use them
473
+ as needed. Consider the `nextmv cloud app list` command, in the `cloud/app/list.py`
474
+ file:
475
+
476
+ ```python
477
+ @app.command()
478
+ def list(
479
+ output: Annotated[
480
+ str | None,
481
+ typer.Option(
482
+ "--output",
483
+ "-o",
484
+ help="Saves the app list information to this location.",
485
+ metavar="OUTPUT_PATH",
486
+ ),
487
+ ] = None,
488
+ profile: ProfileOption = None,
489
+ ) -> None:
490
+ ```
491
+
492
+ The `profile` option's type is `ProfileOption`, which is imported from the
493
+ `options.py` file.
494
+
495
+ - If a command outputs `JSON` content, try to always provide an `output` option
496
+ to allow the user to save the output to a file. Consider the `nextmv cloud
497
+ app list` command again. It has an `output` option that allows the user to
498
+ save the list of applications to a file.
499
+ - Always order command options alphabetically. Required options (without
500
+ default values) should be listed first, in alphabetical order. Optional
501
+ options (with default values) should follow, also in alphabetical order. When
502
+ using `rich_help_panel` to group options, maintain alphabetical order within
503
+ each panel. This ensures consistency across the CLI and makes it easier to
504
+ locate options in the code. An exception for this is the `profile` option, which
505
+ should always be the last option in the command's signature, for consistency
506
+ across the CLI.
507
+
508
+ [typer]: https://typer.tiangolo.com
509
+ [typer-learn]: https://typer.tiangolo.com/tutorial/
510
+ [rich]: https://rich.readthedocs.io/en/stable/
511
+ [rich-emoji]: https://rich.readthedocs.io/en/latest/markup.html#emoji
@@ -0,0 +1,45 @@
1
+ """
2
+ This module defines the cloud command tree for the Nextmv CLI.
3
+ """
4
+
5
+ import typer
6
+
7
+ from nextmv.cli.cloud.acceptance import app as acceptance_app
8
+ from nextmv.cli.cloud.account import app as account_app
9
+ from nextmv.cli.cloud.app import app as app_app
10
+ from nextmv.cli.cloud.batch import app as batch_app
11
+ from nextmv.cli.cloud.data import app as data_app
12
+ from nextmv.cli.cloud.ensemble import app as ensemble_app
13
+ from nextmv.cli.cloud.input_set import app as input_set_app
14
+ from nextmv.cli.cloud.instance import app as instance_app
15
+ from nextmv.cli.cloud.managed_input import app as managed_input_app
16
+ from nextmv.cli.cloud.run import app as run_app
17
+ from nextmv.cli.cloud.scenario import app as scenario_app
18
+ from nextmv.cli.cloud.secrets import app as secrets_app
19
+ from nextmv.cli.cloud.upload import app as upload_app
20
+ from nextmv.cli.cloud.version import app as version_app
21
+
22
+ # Set up subcommand application.
23
+ app = typer.Typer()
24
+ app.add_typer(acceptance_app, name="acceptance")
25
+ app.add_typer(account_app, name="account")
26
+ app.add_typer(app_app, name="app")
27
+ app.add_typer(batch_app, name="batch")
28
+ app.add_typer(data_app, name="data")
29
+ app.add_typer(ensemble_app, name="ensemble")
30
+ app.add_typer(input_set_app, name="input-set")
31
+ app.add_typer(instance_app, name="instance")
32
+ app.add_typer(managed_input_app, name="managed-input")
33
+ app.add_typer(run_app, name="run")
34
+ app.add_typer(scenario_app, name="scenario")
35
+ app.add_typer(secrets_app, name="secrets")
36
+ app.add_typer(upload_app, name="upload")
37
+ app.add_typer(version_app, name="version")
38
+
39
+
40
+ @app.callback()
41
+ def callback() -> None:
42
+ """
43
+ Interact with Nextmv Cloud, a platform for deploying and managing decision models.
44
+ """
45
+ pass