nextmv 1.0.0.dev6__tar.gz → 1.0.0.dev7__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 (230) hide show
  1. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/PKG-INFO +2 -2
  2. nextmv-1.0.0.dev7/nextmv/__about__.py +1 -0
  3. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/application/_acceptance.py +13 -8
  4. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/application/_switchback.py +1 -1
  5. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/integration.py +7 -4
  6. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/switchback.py +2 -0
  7. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/pyproject.toml +1 -1
  8. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/integration/cloud/test_integration_cloud.py +212 -3
  9. nextmv-1.0.0.dev6/nextmv/__about__.py +0 -1
  10. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/.gitignore +0 -0
  11. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/LICENSE +0 -0
  12. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/README.md +0 -0
  13. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/__entrypoint__.py +0 -0
  14. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/__init__.py +0 -0
  15. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/_serialization.py +0 -0
  16. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/base_model.py +0 -0
  17. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/CONTRIBUTING.md +0 -0
  18. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/__init__.py +0 -0
  19. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/__init__.py +0 -0
  20. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/acceptance/__init__.py +0 -0
  21. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/acceptance/create.py +0 -0
  22. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/acceptance/delete.py +0 -0
  23. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/acceptance/get.py +0 -0
  24. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/acceptance/list.py +0 -0
  25. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/acceptance/update.py +0 -0
  26. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/account/__init__.py +0 -0
  27. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/account/create.py +0 -0
  28. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/account/delete.py +0 -0
  29. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/account/get.py +0 -0
  30. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/account/update.py +0 -0
  31. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/app/__init__.py +0 -0
  32. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/app/create.py +0 -0
  33. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/app/delete.py +0 -0
  34. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/app/exists.py +0 -0
  35. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/app/get.py +0 -0
  36. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/app/list.py +0 -0
  37. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/app/push.py +0 -0
  38. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/app/update.py +0 -0
  39. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/batch/__init__.py +0 -0
  40. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/batch/create.py +0 -0
  41. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/batch/delete.py +0 -0
  42. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/batch/get.py +0 -0
  43. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/batch/list.py +0 -0
  44. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/batch/metadata.py +0 -0
  45. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/batch/update.py +0 -0
  46. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/data/__init__.py +0 -0
  47. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/data/upload.py +0 -0
  48. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/ensemble/__init__.py +0 -0
  49. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/ensemble/create.py +0 -0
  50. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/ensemble/delete.py +0 -0
  51. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/ensemble/get.py +0 -0
  52. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/ensemble/list.py +0 -0
  53. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/ensemble/update.py +0 -0
  54. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/input_set/__init__.py +0 -0
  55. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/input_set/create.py +0 -0
  56. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/input_set/delete.py +0 -0
  57. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/input_set/get.py +0 -0
  58. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/input_set/list.py +0 -0
  59. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/input_set/update.py +0 -0
  60. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/instance/__init__.py +0 -0
  61. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/instance/create.py +0 -0
  62. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/instance/delete.py +0 -0
  63. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/instance/exists.py +0 -0
  64. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/instance/get.py +0 -0
  65. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/instance/list.py +0 -0
  66. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/instance/update.py +0 -0
  67. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/managed_input/__init__.py +0 -0
  68. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/managed_input/create.py +0 -0
  69. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/managed_input/delete.py +0 -0
  70. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/managed_input/get.py +0 -0
  71. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/managed_input/list.py +0 -0
  72. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/managed_input/update.py +0 -0
  73. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/run/__init__.py +0 -0
  74. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/run/cancel.py +0 -0
  75. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/run/create.py +0 -0
  76. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/run/get.py +0 -0
  77. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/run/input.py +0 -0
  78. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/run/list.py +0 -0
  79. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/run/logs.py +0 -0
  80. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/run/metadata.py +0 -0
  81. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/run/track.py +0 -0
  82. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/scenario/__init__.py +0 -0
  83. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/scenario/create.py +0 -0
  84. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/scenario/delete.py +0 -0
  85. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/scenario/get.py +0 -0
  86. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/scenario/list.py +0 -0
  87. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/scenario/metadata.py +0 -0
  88. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/scenario/update.py +0 -0
  89. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/secrets/__init__.py +0 -0
  90. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/secrets/create.py +0 -0
  91. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/secrets/delete.py +0 -0
  92. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/secrets/get.py +0 -0
  93. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/secrets/list.py +0 -0
  94. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/secrets/update.py +0 -0
  95. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/shadow/__init__.py +0 -0
  96. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/shadow/create.py +0 -0
  97. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/shadow/delete.py +0 -0
  98. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/shadow/get.py +0 -0
  99. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/shadow/list.py +0 -0
  100. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/shadow/metadata.py +0 -0
  101. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/shadow/start.py +0 -0
  102. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/shadow/stop.py +0 -0
  103. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/shadow/update.py +0 -0
  104. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/switchback/__init__.py +0 -0
  105. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/switchback/create.py +0 -0
  106. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/switchback/delete.py +0 -0
  107. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/switchback/get.py +0 -0
  108. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/switchback/list.py +0 -0
  109. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/switchback/metadata.py +0 -0
  110. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/switchback/start.py +0 -0
  111. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/switchback/stop.py +0 -0
  112. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/switchback/update.py +0 -0
  113. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/upload/__init__.py +0 -0
  114. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/upload/create.py +0 -0
  115. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/version/__init__.py +0 -0
  116. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/version/create.py +0 -0
  117. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/version/delete.py +0 -0
  118. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/version/exists.py +0 -0
  119. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/version/get.py +0 -0
  120. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/version/list.py +0 -0
  121. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/cloud/version/update.py +0 -0
  122. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/community/__init__.py +0 -0
  123. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/community/clone.py +0 -0
  124. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/community/list.py +0 -0
  125. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/configuration/__init__.py +0 -0
  126. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/configuration/config.py +0 -0
  127. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/configuration/create.py +0 -0
  128. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/configuration/delete.py +0 -0
  129. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/configuration/list.py +0 -0
  130. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/confirm.py +0 -0
  131. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/main.py +0 -0
  132. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/message.py +0 -0
  133. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/options.py +0 -0
  134. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cli/version.py +0 -0
  135. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/__init__.py +0 -0
  136. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/acceptance_test.py +0 -0
  137. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/account.py +0 -0
  138. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/application/__init__.py +0 -0
  139. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/application/_batch_scenario.py +0 -0
  140. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/application/_ensemble.py +0 -0
  141. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/application/_input_set.py +0 -0
  142. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/application/_instance.py +0 -0
  143. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/application/_managed_input.py +0 -0
  144. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/application/_run.py +0 -0
  145. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/application/_secrets.py +0 -0
  146. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/application/_shadow.py +0 -0
  147. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/application/_utils.py +0 -0
  148. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/application/_version.py +0 -0
  149. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/assets.py +0 -0
  150. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/batch_experiment.py +0 -0
  151. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/client.py +0 -0
  152. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/community.py +0 -0
  153. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/ensemble.py +0 -0
  154. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/input_set.py +0 -0
  155. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/instance.py +0 -0
  156. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/package.py +0 -0
  157. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/scenario.py +0 -0
  158. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/secrets.py +0 -0
  159. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/shadow.py +0 -0
  160. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/url.py +0 -0
  161. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/cloud/version.py +0 -0
  162. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/default_app/.gitignore +0 -0
  163. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/default_app/README.md +0 -0
  164. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/default_app/app.yaml +0 -0
  165. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/default_app/input.json +0 -0
  166. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/default_app/main.py +0 -0
  167. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/default_app/requirements.txt +0 -0
  168. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/default_app/src/__init__.py +0 -0
  169. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/default_app/src/visuals.py +0 -0
  170. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/deprecated.py +0 -0
  171. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/input.py +0 -0
  172. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/local/__init__.py +0 -0
  173. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/local/application.py +0 -0
  174. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/local/executor.py +0 -0
  175. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/local/geojson_handler.py +0 -0
  176. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/local/local.py +0 -0
  177. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/local/plotly_handler.py +0 -0
  178. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/local/runner.py +0 -0
  179. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/logger.py +0 -0
  180. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/manifest.py +0 -0
  181. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/model.py +0 -0
  182. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/options.py +0 -0
  183. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/output.py +0 -0
  184. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/polling.py +0 -0
  185. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/run.py +0 -0
  186. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/safe.py +0 -0
  187. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/nextmv/status.py +0 -0
  188. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/README.md +0 -0
  189. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/__init__.py +0 -0
  190. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/cli/__init__.py +0 -0
  191. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/cli/test_configuration.py +0 -0
  192. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/cli/test_main.py +0 -0
  193. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/cli/test_version.py +0 -0
  194. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/cloud/__init__.py +0 -0
  195. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/cloud/app.yaml +0 -0
  196. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/cloud/test_client.py +0 -0
  197. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/cloud/test_instance.py +0 -0
  198. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/cloud/test_package.py +0 -0
  199. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/cloud/test_scenario.py +0 -0
  200. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/integration/__init__.py +0 -0
  201. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/integration/cloud/__init__.py +0 -0
  202. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/local/__init__.py +0 -0
  203. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/local/test_application.py +0 -0
  204. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/local/test_executor.py +0 -0
  205. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/local/test_runner.py +0 -0
  206. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/scripts/__init__.py +0 -0
  207. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/scripts/options1.py +0 -0
  208. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/scripts/options2.py +0 -0
  209. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/scripts/options3.py +0 -0
  210. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/scripts/options4.py +0 -0
  211. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/scripts/options5.py +0 -0
  212. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/scripts/options6.py +0 -0
  213. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/scripts/options7.py +0 -0
  214. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/test_base_model.py +0 -0
  215. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/test_entrypoint/__init__.py +0 -0
  216. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/test_entrypoint/test_entrypoint.py +0 -0
  217. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/test_input.py +0 -0
  218. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/test_inputs/test_data.csv +0 -0
  219. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/test_inputs/test_data.json +0 -0
  220. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/test_inputs/test_data.txt +0 -0
  221. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/test_logger.py +0 -0
  222. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/test_manifest.py +0 -0
  223. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/test_model.py +0 -0
  224. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/test_options.py +0 -0
  225. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/test_output.py +0 -0
  226. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/test_polling.py +0 -0
  227. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/test_run.py +0 -0
  228. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/test_safe.py +0 -0
  229. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/test_serialization.py +0 -0
  230. {nextmv-1.0.0.dev6 → nextmv-1.0.0.dev7}/tests/test_version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nextmv
3
- Version: 1.0.0.dev6
3
+ Version: 1.0.0.dev7
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/
@@ -230,7 +230,7 @@ Provides-Extra: dev
230
230
  Requires-Dist: build>=1.0.3; extra == 'dev'
231
231
  Requires-Dist: folium>=0.20.0; extra == 'dev'
232
232
  Requires-Dist: mlflow>=2.19.0; extra == 'dev'
233
- Requires-Dist: nextpipe>=0.6.0.dev0; extra == 'dev'
233
+ Requires-Dist: nextpipe>=0.6.0; extra == 'dev'
234
234
  Requires-Dist: nextroute>=1.11.1; extra == 'dev'
235
235
  Requires-Dist: openpyxl>=3.1.5; extra == 'dev'
236
236
  Requires-Dist: pandas>=2.2.3; extra == 'dev'
@@ -0,0 +1 @@
1
+ __version__ = "v1.0.0.dev7"
@@ -9,6 +9,7 @@ import requests
9
9
  from nextmv.cloud.acceptance_test import AcceptanceTest, Metric
10
10
  from nextmv.cloud.batch_experiment import BatchExperimentRun, ExperimentStatus
11
11
  from nextmv.polling import DEFAULT_POLLING_OPTIONS, PollingOptions, poll
12
+ from nextmv.safe import safe_id
12
13
 
13
14
  if TYPE_CHECKING:
14
15
  from . import Application
@@ -163,8 +164,8 @@ class ApplicationAcceptanceMixin:
163
164
  self: "Application",
164
165
  candidate_instance_id: str,
165
166
  baseline_instance_id: str,
166
- id: str,
167
167
  metrics: list[Metric | dict[str, Any]],
168
+ id: str | None = None,
168
169
  name: str | None = None,
169
170
  input_set_id: str | None = None,
170
171
  description: str | None = None,
@@ -185,8 +186,8 @@ class ApplicationAcceptanceMixin:
185
186
  ID of the candidate instance.
186
187
  baseline_instance_id : str
187
188
  ID of the baseline instance.
188
- id : str
189
- ID of the acceptance test.
189
+ id : str | None, default=None
190
+ ID of the acceptance test. Will be generated if not provided.
190
191
  metrics : list[Union[Metric, dict[str, Any]]]
191
192
  List of metrics to use for the acceptance test.
192
193
  name : Optional[str], default=None
@@ -210,6 +211,11 @@ class ApplicationAcceptanceMixin:
210
211
  If the batch experiment ID does not match the acceptance test ID.
211
212
  """
212
213
 
214
+ # Generate ID if not provided
215
+ if id is None or id == "":
216
+ id = safe_id("acceptance")
217
+
218
+ # Use ID as name if name not provided
213
219
  if name is None or name == "":
214
220
  name = id
215
221
 
@@ -265,11 +271,10 @@ class ApplicationAcceptanceMixin:
265
271
  "metrics": payload_metrics,
266
272
  "experiment_id": batch_experiment_id,
267
273
  "name": name,
274
+ "id": id,
268
275
  }
269
276
  if description is not None:
270
277
  payload["description"] = description
271
- if id is not None:
272
- payload["id"] = id
273
278
 
274
279
  response = self.client.request(
275
280
  method="POST",
@@ -283,8 +288,8 @@ class ApplicationAcceptanceMixin:
283
288
  self: "Application",
284
289
  candidate_instance_id: str,
285
290
  baseline_instance_id: str,
286
- id: str,
287
291
  metrics: list[Metric | dict[str, Any]],
292
+ id: str | None = None,
288
293
  name: str | None = None,
289
294
  input_set_id: str | None = None,
290
295
  description: str | None = None,
@@ -302,8 +307,8 @@ class ApplicationAcceptanceMixin:
302
307
  ID of the candidate instance.
303
308
  baseline_instance_id : str
304
309
  ID of the baseline instance.
305
- id : str
306
- ID of the acceptance test.
310
+ id : str | None, default=None
311
+ ID of the acceptance test. Will be generated if not provided.
307
312
  metrics : list[Union[Metric, dict[str, Any]]]
308
313
  List of metrics to use for the acceptance test.
309
314
  name : Optional[str], default=None
@@ -217,7 +217,7 @@ class ApplicationSwitchbackMixin:
217
217
  payload = {
218
218
  "id": switchback_test_id,
219
219
  "name": name,
220
- "comparison": comparison,
220
+ "comparison": comparison.to_dict(),
221
221
  "generate_random_plan": {
222
222
  "unit_duration_minutes": unit_duration_minutes,
223
223
  "units": units,
@@ -225,12 +225,12 @@ class Integration(BaseModel):
225
225
  def new( # noqa: C901
226
226
  cls,
227
227
  client: Client,
228
- name: str,
229
228
  integration_type: IntegrationType | str,
230
229
  exec_types: list[ManifestType | str],
231
230
  provider: IntegrationProvider | str,
232
231
  provider_config: dict[str, Any],
233
232
  integration_id: str | None = None,
233
+ name: str | None = None,
234
234
  description: str | None = None,
235
235
  is_global: bool = False,
236
236
  application_ids: list[str] | None = None,
@@ -243,8 +243,6 @@ class Integration(BaseModel):
243
243
  ----------
244
244
  client : Client
245
245
  Client to use for interacting with the Nextmv Cloud API.
246
- name : str
247
- The name of the integration.
248
246
  integration_type : IntegrationType | str
249
247
  The type of the integration. Please refer to the `IntegrationType`
250
248
  enum for possible values.
@@ -259,6 +257,9 @@ class Integration(BaseModel):
259
257
  integration_id : str, optional
260
258
  The unique identifier of the integration. If not provided,
261
259
  it will be generated automatically.
260
+ name : str | None, optional
261
+ The name of the integration. If not provided, the integration ID
262
+ will be used as the name.
262
263
  description : str, optional
263
264
  An optional description of the integration.
264
265
  is_global : bool, optional, default=False
@@ -302,8 +303,10 @@ class Integration(BaseModel):
302
303
  elif not is_global and application_ids is None:
303
304
  raise ValueError("A non-global integration must have specific application IDs.")
304
305
 
305
- if integration_id is None:
306
+ if integration_id is None or integration_id == "":
306
307
  integration_id = safe_id("integration")
308
+ if name is None or name == "":
309
+ name = integration_id
307
310
 
308
311
  if exist_ok:
309
312
  try:
@@ -45,6 +45,8 @@ class TestComparisonSingle(BaseModel):
45
45
  ID of the candidate instance for comparison.
46
46
  """
47
47
 
48
+ __test__ = False # Prevents pytest from collecting this class as a test case
49
+
48
50
  baseline_instance_id: str
49
51
  """ID of the baseline instance for comparison."""
50
52
  candidate_instance_id: str
@@ -80,7 +80,7 @@ dev = [
80
80
  "folium>=0.20.0",
81
81
  "plotly>=6.0.1",
82
82
  "pytest>=9.0.2",
83
- "nextpipe>=0.6.0.dev0",
83
+ "nextpipe>=0.6.0",
84
84
  ]
85
85
 
86
86
  [tool.hatch.version]
@@ -447,9 +447,10 @@ class CloudIntegrationWorkflow(FlowSpec):
447
447
  # We can delete a shadow test.
448
448
  app.delete_shadow_test(shadow_test_id=shadow_test.shadow_test_id)
449
449
 
450
- @needs(predecessors=[init_app, instances])
450
+ # We make switchback a successor of shadow tests to reuse the instances.
451
+ @needs(predecessors=[init_app, instances, shadow_tests])
451
452
  @step
452
- def switchback_tests(app: cloud.Application, instances: tuple[cloud.Instance, cloud.Instance]) -> None:
453
+ def switchback_tests(app: cloud.Application, instances: tuple[cloud.Instance, cloud.Instance], __unused) -> None:
453
454
  """
454
455
  Performs switchback test operations.
455
456
 
@@ -467,7 +468,7 @@ class CloudIntegrationWorkflow(FlowSpec):
467
468
  switchback_test = app.new_switchback_test(
468
469
  comparison=TestComparisonSingle(
469
470
  baseline_instance_id=inst1.id,
470
- treatment_instance_id=inst2.id,
471
+ candidate_instance_id=inst2.id,
471
472
  ),
472
473
  unit_duration_minutes=1,
473
474
  units=1,
@@ -522,6 +523,208 @@ class CloudIntegrationWorkflow(FlowSpec):
522
523
  # We can delete a switchback test.
523
524
  app.delete_switchback_test(switchback_test_id=switchback_test.switchback_test_id)
524
525
 
526
+ @needs(predecessors=[init_app, instances, input_sets])
527
+ @step
528
+ def acceptance_tests(
529
+ app: cloud.Application,
530
+ instances: tuple[cloud.Instance, cloud.Instance],
531
+ input_set: cloud.InputSet,
532
+ ) -> None:
533
+ """
534
+ Performs acceptance test operations.
535
+
536
+ Parameters
537
+ ----------
538
+ app : cloud.Application
539
+ The application to perform acceptance test operations on.
540
+ instances : tuple[cloud.Instance, cloud.Instance]
541
+ The instances to use for the acceptance test.
542
+ input_set : cloud.InputSet
543
+ The input set to use for the acceptance test.
544
+ """
545
+
546
+ inst1, inst2 = instances
547
+
548
+ # We can create an acceptance test.
549
+ acceptance = app.new_acceptance_test_with_result(
550
+ baseline_instance_id=inst1.id,
551
+ candidate_instance_id=inst2.id,
552
+ metrics=[
553
+ cloud.Metric(
554
+ field="result.value",
555
+ metric_type=cloud.MetricType.direct_comparison,
556
+ params=cloud.MetricParams(
557
+ operator=cloud.Comparison.equal_to,
558
+ tolerance=cloud.MetricTolerance(
559
+ type=cloud.MetricToleranceType.absolute,
560
+ value=0.01,
561
+ ),
562
+ ),
563
+ statistic=cloud.StatisticType.mean,
564
+ ),
565
+ ],
566
+ input_set_id=input_set.id,
567
+ )
568
+ assert acceptance is not None
569
+
570
+ # We can list acceptance tests.
571
+ acceptance_tests = app.list_acceptance_tests()
572
+ assert len(acceptance_tests) >= 1
573
+ acceptance_test_ids = {a.id for a in acceptance_tests}
574
+ assert acceptance.id in acceptance_test_ids
575
+
576
+ # We can get an acceptance test.
577
+ acceptance = app.acceptance_test(acceptance_test_id=acceptance.id)
578
+ assert acceptance is not None
579
+
580
+ # We can update an acceptance test.
581
+ name = "Hoppy Acceptance & Light"
582
+ description = "An acceptance test for hoppy bunnies"
583
+ acceptance = app.update_acceptance_test(
584
+ acceptance_test_id=acceptance.id,
585
+ name=name,
586
+ description=description,
587
+ )
588
+ assert acceptance.name == name
589
+ assert acceptance.description == description
590
+
591
+ # We can delete an acceptance test.
592
+ app.delete_acceptance_test(acceptance_test_id=acceptance.id)
593
+
594
+ @needs(predecessors=[init_app, community_push])
595
+ @step
596
+ def secrets(app: cloud.Application, __unused) -> None:
597
+ """
598
+ Performs secret operations.
599
+
600
+ Parameters
601
+ ----------
602
+ app : cloud.Application
603
+ The application to perform secret operations on.
604
+ """
605
+
606
+ # We can create a secrets collection.
607
+ secrets = [
608
+ cloud.Secret(
609
+ secret_type=cloud.SecretType.ENV,
610
+ location="BURROW_ENTRANCE",
611
+ value="Make 2 lefts and a hop forward",
612
+ )
613
+ ]
614
+ summary = app.new_secrets_collection(
615
+ secrets=secrets,
616
+ )
617
+
618
+ # We can get a secrets collection.
619
+ collection = app.secrets_collection(secrets_collection_id=summary.collection_id)
620
+ assert collection is not None
621
+ assert len(collection.secrets) == 1
622
+ assert collection.secrets[0].location == secrets[0].location
623
+ assert collection.secrets[0].value == secrets[0].value
624
+
625
+ # We can list secret collections.
626
+ collections = app.list_secrets_collections()
627
+ assert len(collections) >= 1
628
+ collection_ids = {c.collection_id for c in collections}
629
+ assert summary.collection_id in collection_ids
630
+
631
+ # We can update a secrets collection.
632
+ name = "Bunny Secrets"
633
+ description = "Secrets for bunny application"
634
+ summary = app.update_secrets_collection(
635
+ secrets_collection_id=summary.collection_id,
636
+ name=name,
637
+ description=description,
638
+ )
639
+ assert summary.name == name
640
+ assert summary.description == description
641
+
642
+ # We can start a run using the secrets collection.
643
+ input_data = {"name": "world", "radius": 6378, "distance": 147.6}
644
+ app.new_run(
645
+ input=input_data,
646
+ configuration=nextmv.RunConfiguration(
647
+ secrets_collection_id=summary.collection_id,
648
+ ),
649
+ )
650
+
651
+ # We can delete a secrets collection.
652
+ app.delete_secrets_collection(secrets_collection_id=summary.collection_id)
653
+
654
+ @needs(predecessors=[init_app, instances])
655
+ @step
656
+ def ensembles(app: cloud.Application, instances: tuple[cloud.Instance, cloud.Instance]) -> None:
657
+ """
658
+ Performs ensemble operations.
659
+
660
+ Parameters
661
+ ----------
662
+ app : cloud.Application
663
+ The application to perform ensemble operations on.
664
+ instances : tuple[cloud.Instance, cloud.Instance]
665
+ The instances to use for the ensemble definition.
666
+ """
667
+
668
+ inst1, _ = instances
669
+
670
+ # We can create an ensemble definition.
671
+ definition = app.new_ensemble_definition(
672
+ run_groups=[
673
+ cloud.RunGroup(
674
+ id="run-group-1",
675
+ instance_id=inst1.id,
676
+ ),
677
+ ],
678
+ rules=[
679
+ cloud.EvaluationRule(
680
+ id="eval-rule-1",
681
+ statistics_path="result.value",
682
+ objective=cloud.RuleObjective.MAXIMIZE,
683
+ tolerance=cloud.RuleTolerance(
684
+ value=0.01,
685
+ type=cloud.RuleToleranceType.ABSOLUTE,
686
+ ),
687
+ index=0,
688
+ ),
689
+ ],
690
+ )
691
+
692
+ # We can get an ensemble definition.
693
+ definition = app.ensemble_definition(ensemble_definition_id=definition.id)
694
+ assert definition is not None
695
+
696
+ # We can list ensemble definitions.
697
+ definitions = app.list_ensemble_definitions()
698
+ assert len(definitions) >= 1
699
+ definition_ids = {d.id for d in definitions}
700
+ assert definition.id in definition_ids
701
+
702
+ # We can update an ensemble definition.
703
+ name = "Bunny Ensemble"
704
+ description = "Ensemble for bunny runs"
705
+ definition = app.update_ensemble_definition(
706
+ id=definition.id,
707
+ name=name,
708
+ description=description,
709
+ )
710
+ assert definition.name == name
711
+ assert definition.description == description
712
+
713
+ # We can start an ensemble run.
714
+ input_data = {"name": "world", "radius": 6378, "distance": 147.6}
715
+ app.new_run(
716
+ input=input_data,
717
+ configuration=nextmv.RunConfiguration(
718
+ run_type=nextmv.RunTypeConfiguration(
719
+ run_type=nextmv.RunType.ENSEMBLE,
720
+ definition_id=definition.id,
721
+ ),
722
+ ),
723
+ )
724
+
725
+ # We can delete an ensemble definition.
726
+ app.delete_ensemble_definition(ensemble_definition_id=definition.id)
727
+
525
728
  # For this step, all other steps are predecessors to make sure there are no
526
729
  # on-going processes before cleanup.
527
730
  @needs(
@@ -534,6 +737,9 @@ class CloudIntegrationWorkflow(FlowSpec):
534
737
  scenario_tests,
535
738
  shadow_tests,
536
739
  switchback_tests,
740
+ acceptance_tests,
741
+ secrets,
742
+ ensembles,
537
743
  ]
538
744
  )
539
745
  @step
@@ -546,6 +752,9 @@ class CloudIntegrationWorkflow(FlowSpec):
546
752
  __unused2,
547
753
  __unused3,
548
754
  __unused4,
755
+ __unused5,
756
+ __unused6,
757
+ __unused7,
549
758
  ) -> None:
550
759
  """Performs cleanup operations."""
551
760
 
@@ -1 +0,0 @@
1
- __version__ = "v1.0.0.dev6"
File without changes
File without changes
File without changes