qwak-sdk 0.5.102__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 (328) hide show
  1. qwak_sdk/__init__.py +9 -0
  2. qwak_sdk/cli.py +79 -0
  3. qwak_sdk/commands/__init__.py +0 -0
  4. qwak_sdk/commands/_logic/__init__.py +0 -0
  5. qwak_sdk/commands/_logic/tools.py +6 -0
  6. qwak_sdk/commands/admin/__init__.py +0 -0
  7. qwak_sdk/commands/admin/admin_commands_group.py +17 -0
  8. qwak_sdk/commands/admin/apikeys/__init__.py +0 -0
  9. qwak_sdk/commands/admin/apikeys/api_keys_commands_group.py +17 -0
  10. qwak_sdk/commands/admin/apikeys/generate/__init__.py +0 -0
  11. qwak_sdk/commands/admin/apikeys/generate/_logic.py +21 -0
  12. qwak_sdk/commands/admin/apikeys/generate/ui.py +45 -0
  13. qwak_sdk/commands/admin/apikeys/revoke/__init__.py +0 -0
  14. qwak_sdk/commands/admin/apikeys/revoke/_logic.py +22 -0
  15. qwak_sdk/commands/admin/apikeys/revoke/ui.py +31 -0
  16. qwak_sdk/commands/alerts/__init__.py +0 -0
  17. qwak_sdk/commands/alerts/alerts_commnad_group.py +18 -0
  18. qwak_sdk/commands/alerts/delete/__init__.py +0 -0
  19. qwak_sdk/commands/alerts/delete/_logic.py +5 -0
  20. qwak_sdk/commands/alerts/delete/ui.py +10 -0
  21. qwak_sdk/commands/alerts/list/__init__.py +0 -0
  22. qwak_sdk/commands/alerts/list/_logic.py +23 -0
  23. qwak_sdk/commands/alerts/list/ui.py +17 -0
  24. qwak_sdk/commands/alerts/register/__init__.py +0 -0
  25. qwak_sdk/commands/alerts/register/_logic.py +72 -0
  26. qwak_sdk/commands/alerts/register/ui.py +30 -0
  27. qwak_sdk/commands/audience/__init__.py +0 -0
  28. qwak_sdk/commands/audience/_logic/__init__.py +0 -0
  29. qwak_sdk/commands/audience/_logic/config/__init__.py +0 -0
  30. qwak_sdk/commands/audience/_logic/config/config_base.py +15 -0
  31. qwak_sdk/commands/audience/_logic/config/parser.py +30 -0
  32. qwak_sdk/commands/audience/_logic/config/v1/__init__.py +0 -0
  33. qwak_sdk/commands/audience/_logic/config/v1/audience_config.py +26 -0
  34. qwak_sdk/commands/audience/_logic/config/v1/conditions_config.py +59 -0
  35. qwak_sdk/commands/audience/_logic/config/v1/config_v1.py +23 -0
  36. qwak_sdk/commands/audience/_logic/config/v1/route_config.py +15 -0
  37. qwak_sdk/commands/audience/_logic/config/v1/spec.py +9 -0
  38. qwak_sdk/commands/audience/audience_api_dump.py +86 -0
  39. qwak_sdk/commands/audience/audience_commands_group.py +30 -0
  40. qwak_sdk/commands/audience/create/__init__.py +0 -0
  41. qwak_sdk/commands/audience/create/logic.py +41 -0
  42. qwak_sdk/commands/audience/create/ui.py +21 -0
  43. qwak_sdk/commands/audience/delete/__init__.py +0 -0
  44. qwak_sdk/commands/audience/delete/logic.py +13 -0
  45. qwak_sdk/commands/audience/delete/ui.py +17 -0
  46. qwak_sdk/commands/audience/get/__init__.py +0 -0
  47. qwak_sdk/commands/audience/get/logic.py +14 -0
  48. qwak_sdk/commands/audience/get/ui.py +25 -0
  49. qwak_sdk/commands/audience/list/__init__.py +0 -0
  50. qwak_sdk/commands/audience/list/logic.py +16 -0
  51. qwak_sdk/commands/audience/list/ui.py +26 -0
  52. qwak_sdk/commands/audience/update/__init__.py +0 -0
  53. qwak_sdk/commands/audience/update/logic.py +37 -0
  54. qwak_sdk/commands/audience/update/ui.py +26 -0
  55. qwak_sdk/commands/auto_scalling/__init__.py +0 -0
  56. qwak_sdk/commands/auto_scalling/_logic/__init__.py +0 -0
  57. qwak_sdk/commands/auto_scalling/_logic/config/__init__.py +3 -0
  58. qwak_sdk/commands/auto_scalling/_logic/config/config.py +152 -0
  59. qwak_sdk/commands/auto_scalling/_logic/config/parser.py +21 -0
  60. qwak_sdk/commands/auto_scalling/attach/__init__.py +0 -0
  61. qwak_sdk/commands/auto_scalling/attach/_logic.py +43 -0
  62. qwak_sdk/commands/auto_scalling/attach/ui.py +21 -0
  63. qwak_sdk/commands/auto_scalling/autoscaling_commands_group.py +15 -0
  64. qwak_sdk/commands/automations/__init__.py +0 -0
  65. qwak_sdk/commands/automations/automations_commands_group.py +30 -0
  66. qwak_sdk/commands/automations/delete/__init__.py +0 -0
  67. qwak_sdk/commands/automations/delete/_logic.py +6 -0
  68. qwak_sdk/commands/automations/delete/ui.py +23 -0
  69. qwak_sdk/commands/automations/executions/__init__.py +0 -0
  70. qwak_sdk/commands/automations/executions/executions_commands_group.py +14 -0
  71. qwak_sdk/commands/automations/executions/list/__init__.py +0 -0
  72. qwak_sdk/commands/automations/executions/list/_logic.py +8 -0
  73. qwak_sdk/commands/automations/executions/list/ui.py +25 -0
  74. qwak_sdk/commands/automations/list/__init__.py +0 -0
  75. qwak_sdk/commands/automations/list/_logic.py +36 -0
  76. qwak_sdk/commands/automations/list/ui.py +21 -0
  77. qwak_sdk/commands/automations/register/__init__.py +0 -0
  78. qwak_sdk/commands/automations/register/_logic.py +43 -0
  79. qwak_sdk/commands/automations/register/ui.py +44 -0
  80. qwak_sdk/commands/feature_store/__init__.py +0 -0
  81. qwak_sdk/commands/feature_store/backfill/__init__.py +0 -0
  82. qwak_sdk/commands/feature_store/backfill/_logic.py +140 -0
  83. qwak_sdk/commands/feature_store/backfill/streaming/__init__.py +0 -0
  84. qwak_sdk/commands/feature_store/backfill/streaming/_logic.py +50 -0
  85. qwak_sdk/commands/feature_store/backfill/streaming/ui.py +67 -0
  86. qwak_sdk/commands/feature_store/backfill/ui.py +146 -0
  87. qwak_sdk/commands/feature_store/delete/__init__.py +0 -0
  88. qwak_sdk/commands/feature_store/delete/_logic.py +104 -0
  89. qwak_sdk/commands/feature_store/delete/ui.py +40 -0
  90. qwak_sdk/commands/feature_store/execution/__init__.py +0 -0
  91. qwak_sdk/commands/feature_store/execution/ui.py +19 -0
  92. qwak_sdk/commands/feature_store/feature_store_command_group.py +29 -0
  93. qwak_sdk/commands/feature_store/list/__init__.py +0 -0
  94. qwak_sdk/commands/feature_store/list/ui.py +140 -0
  95. qwak_sdk/commands/feature_store/pause/__init__.py +0 -0
  96. qwak_sdk/commands/feature_store/pause/ui.py +18 -0
  97. qwak_sdk/commands/feature_store/register/__init__.py +0 -0
  98. qwak_sdk/commands/feature_store/register/_logic.py +367 -0
  99. qwak_sdk/commands/feature_store/register/ui.py +111 -0
  100. qwak_sdk/commands/feature_store/resume/__init__.py +0 -0
  101. qwak_sdk/commands/feature_store/resume/ui.py +18 -0
  102. qwak_sdk/commands/feature_store/trigger/__init__.py +0 -0
  103. qwak_sdk/commands/feature_store/trigger/ui.py +39 -0
  104. qwak_sdk/commands/models/__init__.py +0 -0
  105. qwak_sdk/commands/models/build/__init__.py +0 -0
  106. qwak_sdk/commands/models/build/_logic/__init__.py +0 -0
  107. qwak_sdk/commands/models/build/_logic/build_steps.py +42 -0
  108. qwak_sdk/commands/models/build/_logic/client_logs/__init__.py +0 -0
  109. qwak_sdk/commands/models/build/_logic/client_logs/cli_phase_run_handler.py +123 -0
  110. qwak_sdk/commands/models/build/_logic/client_logs/cli_trigger_build_logger.py +19 -0
  111. qwak_sdk/commands/models/build/_logic/client_logs/logger.py +88 -0
  112. qwak_sdk/commands/models/build/_logic/client_logs/messages.py +36 -0
  113. qwak_sdk/commands/models/build/_logic/client_logs/spinner.py +14 -0
  114. qwak_sdk/commands/models/build/_logic/client_logs/trigger_build_logger.py +54 -0
  115. qwak_sdk/commands/models/build/_logic/client_logs/utils.py +12 -0
  116. qwak_sdk/commands/models/build/_logic/phase/__init__.py +0 -0
  117. qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/__init__.py +20 -0
  118. qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/get_sdk_version_step.py +14 -0
  119. qwak_sdk/commands/models/build/_logic/phase/b_remote_register_qwak_build/__init__.py +16 -0
  120. qwak_sdk/commands/models/build/_logic/phase/c_deploy/__init__.py +6 -0
  121. qwak_sdk/commands/models/build/_logic/phase/c_deploy/build_polling_status.py +55 -0
  122. qwak_sdk/commands/models/build/_logic/phase/c_deploy/deploy_build.py +61 -0
  123. qwak_sdk/commands/models/build/_logic/util/__init__.py +0 -0
  124. qwak_sdk/commands/models/build/_logic/util/protobuf_factory.py +45 -0
  125. qwak_sdk/commands/models/build/_logic/util/step_decorator.py +60 -0
  126. qwak_sdk/commands/models/build/_logic/util/text.py +9 -0
  127. qwak_sdk/commands/models/build/_logic/wait_until_finished.py +27 -0
  128. qwak_sdk/commands/models/build/ui.py +337 -0
  129. qwak_sdk/commands/models/builds/__init__.py +0 -0
  130. qwak_sdk/commands/models/builds/builds_commands_group.py +16 -0
  131. qwak_sdk/commands/models/builds/cancel/__init__.py +0 -0
  132. qwak_sdk/commands/models/builds/cancel/_logic.py +5 -0
  133. qwak_sdk/commands/models/builds/cancel/ui.py +15 -0
  134. qwak_sdk/commands/models/builds/logs/__init__.py +0 -0
  135. qwak_sdk/commands/models/builds/logs/ui.py +35 -0
  136. qwak_sdk/commands/models/builds/status/__init__.py +0 -0
  137. qwak_sdk/commands/models/builds/status/_logic.py +6 -0
  138. qwak_sdk/commands/models/builds/status/ui.py +39 -0
  139. qwak_sdk/commands/models/create/__init__.py +0 -0
  140. qwak_sdk/commands/models/create/_logic.py +36 -0
  141. qwak_sdk/commands/models/create/ui.py +43 -0
  142. qwak_sdk/commands/models/delete/__init__.py +0 -0
  143. qwak_sdk/commands/models/delete/_logic.py +5 -0
  144. qwak_sdk/commands/models/delete/ui.py +25 -0
  145. qwak_sdk/commands/models/deployments/__init__.py +0 -0
  146. qwak_sdk/commands/models/deployments/deploy/__init__.py +0 -0
  147. qwak_sdk/commands/models/deployments/deploy/_logic/__init__.py +0 -0
  148. qwak_sdk/commands/models/deployments/deploy/_logic/advance_deployment_options_handler.py +31 -0
  149. qwak_sdk/commands/models/deployments/deploy/_logic/base_deploy_executor.py +68 -0
  150. qwak_sdk/commands/models/deployments/deploy/_logic/deploy_config.py +261 -0
  151. qwak_sdk/commands/models/deployments/deploy/_logic/deployment.py +405 -0
  152. qwak_sdk/commands/models/deployments/deploy/_logic/deployment_message_helpers.py +114 -0
  153. qwak_sdk/commands/models/deployments/deploy/_logic/deployment_response_handler.py +156 -0
  154. qwak_sdk/commands/models/deployments/deploy/_logic/deployment_size_mapper.py +96 -0
  155. qwak_sdk/commands/models/deployments/deploy/_logic/get_latest_successful_build.py +28 -0
  156. qwak_sdk/commands/models/deployments/deploy/_logic/local_deployment.py +193 -0
  157. qwak_sdk/commands/models/deployments/deploy/batch/__init__.py +0 -0
  158. qwak_sdk/commands/models/deployments/deploy/batch/_logic/__init__.py +0 -0
  159. qwak_sdk/commands/models/deployments/deploy/batch/_logic/advanced_deployment_mapper.py +15 -0
  160. qwak_sdk/commands/models/deployments/deploy/batch/_logic/deploy_executor.py +24 -0
  161. qwak_sdk/commands/models/deployments/deploy/batch/ui.py +126 -0
  162. qwak_sdk/commands/models/deployments/deploy/deploy_commands_group.py +19 -0
  163. qwak_sdk/commands/models/deployments/deploy/realtime/__init__.py +0 -0
  164. qwak_sdk/commands/models/deployments/deploy/realtime/_logic/__init__.py +0 -0
  165. qwak_sdk/commands/models/deployments/deploy/realtime/_logic/advanced_deployment_mapper.py +21 -0
  166. qwak_sdk/commands/models/deployments/deploy/realtime/_logic/deploy_executor.py +24 -0
  167. qwak_sdk/commands/models/deployments/deploy/realtime/_logic/serving_strategy_mapper.py +75 -0
  168. qwak_sdk/commands/models/deployments/deploy/realtime/ui.py +209 -0
  169. qwak_sdk/commands/models/deployments/deploy/streaming/__init__.py +0 -0
  170. qwak_sdk/commands/models/deployments/deploy/streaming/_logic/__init__.py +0 -0
  171. qwak_sdk/commands/models/deployments/deploy/streaming/_logic/deploy_executor.py +24 -0
  172. qwak_sdk/commands/models/deployments/deploy/streaming/_logic/serving_strategy_mapper.py +38 -0
  173. qwak_sdk/commands/models/deployments/deploy/streaming/ui.py +213 -0
  174. qwak_sdk/commands/models/deployments/undeploy/__init__.py +0 -0
  175. qwak_sdk/commands/models/deployments/undeploy/_logic/__init__.py +0 -0
  176. qwak_sdk/commands/models/deployments/undeploy/_logic/request_undeploy.py +249 -0
  177. qwak_sdk/commands/models/deployments/undeploy/ui.py +72 -0
  178. qwak_sdk/commands/models/describe/__init__.py +0 -0
  179. qwak_sdk/commands/models/describe/_logic.py +169 -0
  180. qwak_sdk/commands/models/describe/ui.py +35 -0
  181. qwak_sdk/commands/models/executions/__init__.py +0 -0
  182. qwak_sdk/commands/models/executions/cancel/__init__.py +0 -0
  183. qwak_sdk/commands/models/executions/cancel/_logic.py +9 -0
  184. qwak_sdk/commands/models/executions/cancel/ui.py +27 -0
  185. qwak_sdk/commands/models/executions/execution_commands_group.py +24 -0
  186. qwak_sdk/commands/models/executions/report/__init__.py +0 -0
  187. qwak_sdk/commands/models/executions/report/_logic.py +14 -0
  188. qwak_sdk/commands/models/executions/report/ui.py +43 -0
  189. qwak_sdk/commands/models/executions/start/__init__.py +0 -0
  190. qwak_sdk/commands/models/executions/start/_logic.py +81 -0
  191. qwak_sdk/commands/models/executions/start/ui.py +208 -0
  192. qwak_sdk/commands/models/executions/status/__init__.py +0 -0
  193. qwak_sdk/commands/models/executions/status/_logic.py +13 -0
  194. qwak_sdk/commands/models/executions/status/ui.py +27 -0
  195. qwak_sdk/commands/models/init/__init__.py +0 -0
  196. qwak_sdk/commands/models/init/_logic/__init__.py +0 -0
  197. qwak_sdk/commands/models/init/_logic/initialize_model_structure.py +40 -0
  198. qwak_sdk/commands/models/init/_logic/template/__init__.py +0 -0
  199. qwak_sdk/commands/models/init/_logic/template/churn/__init__.py +0 -0
  200. qwak_sdk/commands/models/init/_logic/template/churn/cookiecutter.json +3 -0
  201. qwak_sdk/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/__init__.py +0 -0
  202. qwak_sdk/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/main/__init__.py +5 -0
  203. qwak_sdk/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/main/conda.yml +10 -0
  204. qwak_sdk/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/main/data.csv +1001 -0
  205. qwak_sdk/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/main/model.py +95 -0
  206. qwak_sdk/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/tests/__init__.py +0 -0
  207. qwak_sdk/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/tests/it/__init__.py +0 -0
  208. qwak_sdk/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/tests/it/test_churn.py +32 -0
  209. qwak_sdk/commands/models/init/_logic/template/credit_risk/__init__.py +0 -0
  210. qwak_sdk/commands/models/init/_logic/template/credit_risk/cookiecutter.json +3 -0
  211. qwak_sdk/commands/models/init/_logic/template/credit_risk/{{cookiecutter.model_directory}}/__init__.py +0 -0
  212. qwak_sdk/commands/models/init/_logic/template/credit_risk/{{cookiecutter.model_directory}}/main/__init__.py +5 -0
  213. qwak_sdk/commands/models/init/_logic/template/credit_risk/{{cookiecutter.model_directory}}/main/conda.yml +11 -0
  214. qwak_sdk/commands/models/init/_logic/template/credit_risk/{{cookiecutter.model_directory}}/main/data.csv +1001 -0
  215. qwak_sdk/commands/models/init/_logic/template/credit_risk/{{cookiecutter.model_directory}}/main/model.py +108 -0
  216. qwak_sdk/commands/models/init/_logic/template/general/__init__.py +0 -0
  217. qwak_sdk/commands/models/init/_logic/template/general/cookiecutter.json +6 -0
  218. qwak_sdk/commands/models/init/_logic/template/general/{{cookiecutter.model_directory}}/__init__.py +0 -0
  219. qwak_sdk/commands/models/init/_logic/template/general/{{cookiecutter.model_directory}}/{{cookiecutter.main_directory}}/__init__.py +5 -0
  220. qwak_sdk/commands/models/init/_logic/template/general/{{cookiecutter.model_directory}}/{{cookiecutter.main_directory}}/conda.yml +8 -0
  221. qwak_sdk/commands/models/init/_logic/template/general/{{cookiecutter.model_directory}}/{{cookiecutter.main_directory}}/model.py +66 -0
  222. qwak_sdk/commands/models/init/_logic/template/general/{{cookiecutter.model_directory}}/{{cookiecutter.test_directory}}/__init__.py +0 -0
  223. qwak_sdk/commands/models/init/_logic/template/general/{{cookiecutter.model_directory}}/{{cookiecutter.test_directory}}/test_qwak_model.py +5 -0
  224. qwak_sdk/commands/models/init/_logic/template/titanic/__init__.py +0 -0
  225. qwak_sdk/commands/models/init/_logic/template/titanic/cookiecutter.json +3 -0
  226. qwak_sdk/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/__init__.py +0 -0
  227. qwak_sdk/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/main/__init__.py +5 -0
  228. qwak_sdk/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/main/conda.yml +11 -0
  229. qwak_sdk/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/main/model.py +98 -0
  230. qwak_sdk/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/tests/__init__.py +0 -0
  231. qwak_sdk/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/tests/it/__init__.py +0 -0
  232. qwak_sdk/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/tests/it/test_titanic.py +24 -0
  233. qwak_sdk/commands/models/init/_logic/template/titanic_poetry/__init__.py +0 -0
  234. qwak_sdk/commands/models/init/_logic/template/titanic_poetry/cookiecutter.json +3 -0
  235. qwak_sdk/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/__init__.py +0 -0
  236. qwak_sdk/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/main/__init__.py +5 -0
  237. qwak_sdk/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/main/model.py +98 -0
  238. qwak_sdk/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/main/pyproject.toml +20 -0
  239. qwak_sdk/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/tests/__init__.py +0 -0
  240. qwak_sdk/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/tests/it/__init__.py +0 -0
  241. qwak_sdk/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/tests/it/test_titanic.py +25 -0
  242. qwak_sdk/commands/models/init/ui.py +61 -0
  243. qwak_sdk/commands/models/list/__init__.py +0 -0
  244. qwak_sdk/commands/models/list/_logic.py +5 -0
  245. qwak_sdk/commands/models/list/ui.py +40 -0
  246. qwak_sdk/commands/models/list_models/__init__.py +0 -0
  247. qwak_sdk/commands/models/list_models/_logic.py +5 -0
  248. qwak_sdk/commands/models/list_models/ui.py +60 -0
  249. qwak_sdk/commands/models/metadata/__init__.py +0 -0
  250. qwak_sdk/commands/models/metadata/_logic.py +5 -0
  251. qwak_sdk/commands/models/metadata/ui.py +60 -0
  252. qwak_sdk/commands/models/models_command_group.py +44 -0
  253. qwak_sdk/commands/models/runtime/__init__.py +0 -0
  254. qwak_sdk/commands/models/runtime/logs/__init__.py +0 -0
  255. qwak_sdk/commands/models/runtime/logs/ui.py +63 -0
  256. qwak_sdk/commands/models/runtime/runtime_commands_group.py +17 -0
  257. qwak_sdk/commands/models/runtime/update/__init__.py +0 -0
  258. qwak_sdk/commands/models/runtime/update/_logic.py +9 -0
  259. qwak_sdk/commands/models/runtime/update/ui.py +15 -0
  260. qwak_sdk/commands/projects/__init__.py +0 -0
  261. qwak_sdk/commands/projects/create/__init__.py +0 -0
  262. qwak_sdk/commands/projects/create/_logic.py +9 -0
  263. qwak_sdk/commands/projects/create/ui.py +68 -0
  264. qwak_sdk/commands/projects/delete/__init__.py +0 -0
  265. qwak_sdk/commands/projects/delete/_logic.py +6 -0
  266. qwak_sdk/commands/projects/delete/ui.py +24 -0
  267. qwak_sdk/commands/projects/list/__init__.py +0 -0
  268. qwak_sdk/commands/projects/list/_logic.py +6 -0
  269. qwak_sdk/commands/projects/list/ui.py +45 -0
  270. qwak_sdk/commands/projects/projects_command_group.py +19 -0
  271. qwak_sdk/commands/secrets/__init__.py +0 -0
  272. qwak_sdk/commands/secrets/delete/__init__.py +0 -0
  273. qwak_sdk/commands/secrets/delete/_logic.py +5 -0
  274. qwak_sdk/commands/secrets/delete/ui.py +21 -0
  275. qwak_sdk/commands/secrets/get/__init__.py +0 -0
  276. qwak_sdk/commands/secrets/get/_logic.py +5 -0
  277. qwak_sdk/commands/secrets/get/ui.py +17 -0
  278. qwak_sdk/commands/secrets/secrets_commands_group.py +19 -0
  279. qwak_sdk/commands/secrets/set/__init__.py +0 -0
  280. qwak_sdk/commands/secrets/set/_logic.py +5 -0
  281. qwak_sdk/commands/secrets/set/ui.py +16 -0
  282. qwak_sdk/commands/ui_tools.py +18 -0
  283. qwak_sdk/commands/workspaces/__init__.py +0 -0
  284. qwak_sdk/commands/workspaces/_logic/__init__.py +0 -0
  285. qwak_sdk/commands/workspaces/_logic/tools.py +44 -0
  286. qwak_sdk/commands/workspaces/_logic/workspace_validations.py +41 -0
  287. qwak_sdk/commands/workspaces/config/__init__.py +0 -0
  288. qwak_sdk/commands/workspaces/config/workspace_config.py +35 -0
  289. qwak_sdk/commands/workspaces/create/__init__.py +0 -0
  290. qwak_sdk/commands/workspaces/create/_logic.py +54 -0
  291. qwak_sdk/commands/workspaces/create/ui.py +48 -0
  292. qwak_sdk/commands/workspaces/delete/__init__.py +0 -0
  293. qwak_sdk/commands/workspaces/delete/_logic.py +30 -0
  294. qwak_sdk/commands/workspaces/delete/ui.py +23 -0
  295. qwak_sdk/commands/workspaces/start/__init__.py +0 -0
  296. qwak_sdk/commands/workspaces/start/_logic.py +30 -0
  297. qwak_sdk/commands/workspaces/start/ui.py +23 -0
  298. qwak_sdk/commands/workspaces/stop/__init__.py +0 -0
  299. qwak_sdk/commands/workspaces/stop/_logic.py +30 -0
  300. qwak_sdk/commands/workspaces/stop/ui.py +23 -0
  301. qwak_sdk/commands/workspaces/update/__init__.py +0 -0
  302. qwak_sdk/commands/workspaces/update/_logic.py +82 -0
  303. qwak_sdk/commands/workspaces/update/ui.py +57 -0
  304. qwak_sdk/commands/workspaces/workspaces_commands_group.py +23 -0
  305. qwak_sdk/exceptions/__init__.py +11 -0
  306. qwak_sdk/exceptions/qwak_command_exception.py +2 -0
  307. qwak_sdk/exceptions/qwak_deploy_new_build_failed.py +5 -0
  308. qwak_sdk/exceptions/qwak_resource_not_found.py +2 -0
  309. qwak_sdk/inner/__init__.py +0 -0
  310. qwak_sdk/inner/file_registry.py +98 -0
  311. qwak_sdk/inner/tools/__init__.py +0 -0
  312. qwak_sdk/inner/tools/cli_tools.py +220 -0
  313. qwak_sdk/inner/tools/config_handler.py +27 -0
  314. qwak_sdk/inner/tools/dataclasses_utils.py +21 -0
  315. qwak_sdk/inner/tools/logger/__init__.py +3 -0
  316. qwak_sdk/inner/tools/logger/logger.py +269 -0
  317. qwak_sdk/inner/tools/logger/logging.yml +79 -0
  318. qwak_sdk/inner/tools/tracking.py +47 -0
  319. qwak_sdk/main.py +9 -0
  320. qwak_sdk/tools/__init__.py +0 -0
  321. qwak_sdk/tools/colors.py +13 -0
  322. qwak_sdk/tools/files.py +63 -0
  323. qwak_sdk/tools/log_handling.py +159 -0
  324. qwak_sdk/tools/utils.py +42 -0
  325. qwak_sdk-0.5.102.dist-info/METADATA +51 -0
  326. qwak_sdk-0.5.102.dist-info/RECORD +328 -0
  327. qwak_sdk-0.5.102.dist-info/WHEEL +4 -0
  328. qwak_sdk-0.5.102.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,405 @@
1
+ from abc import ABC
2
+ from dataclasses import dataclass, field
3
+ from datetime import datetime
4
+ from enum import Enum
5
+ from typing import Dict, List
6
+
7
+ from _qwak_proto.qwak.audience.v1.audience_pb2 import (
8
+ AudienceRoutesEntry as AudienceProto,
9
+ )
10
+ from _qwak_proto.qwak.audience.v1.audience_pb2 import Route as RouteProto
11
+ from _qwak_proto.qwak.auto_scaling.v1.auto_scaling_pb2 import (
12
+ AutoScalingConfig as AutoScalingProto,
13
+ )
14
+ from _qwak_proto.qwak.deployment.deployment_pb2 import (
15
+ DeploymentDetails as DeploymentProto,
16
+ )
17
+ from _qwak_proto.qwak.deployment.deployment_pb2 import (
18
+ RealTimeConfig as RealTimeConfigProto,
19
+ )
20
+ from _qwak_proto.qwak.deployment.deployment_pb2 import (
21
+ ServingStrategy as ServingStrategyProto,
22
+ )
23
+ from _qwak_proto.qwak.deployment.deployment_pb2 import StreamConfig as StreamConfigProto
24
+
25
+
26
+ @dataclass
27
+ class TrafficSpec:
28
+ percentage: int = field(default=None)
29
+ is_shadow: bool = field(default=None)
30
+
31
+
32
+ @dataclass
33
+ class Variation:
34
+ name: str = field(default=None)
35
+ environment_id: str = field(default=None)
36
+ traffic_spec: TrafficSpec = field(default=None)
37
+
38
+
39
+ @dataclass
40
+ class Route:
41
+ variation_name: str = field(default=None)
42
+ weight: int = field(default=None)
43
+ shadow: bool = field(default=None)
44
+ model_id: str = field(default=None)
45
+ environment_id: str = field(default=None)
46
+ audience_id: str = field(default=None)
47
+
48
+
49
+ @dataclass
50
+ class AudienceRoute:
51
+ audience_id: str = field(default=None)
52
+ audience_name: str = field(default=None)
53
+ routes: List[Route] = field(default_factory=list)
54
+ order: int = field(default=None)
55
+
56
+
57
+ @dataclass
58
+ class EnvironmentAudienceRoute(AudienceRoute):
59
+ environment_id: str = field(default=None)
60
+
61
+ @staticmethod
62
+ def from_proto(environment_id: str, proto: AudienceProto):
63
+ return EnvironmentAudienceRoute(
64
+ audience_id=proto.audience_id,
65
+ audience_name=proto.audience_name,
66
+ routes=Deployment.parse_routes(proto.routes),
67
+ order=proto.order,
68
+ environment_id=environment_id,
69
+ )
70
+
71
+
72
+ class Metric(Enum):
73
+ NOT_VALID = 0
74
+ CPU = 1
75
+ MEMORY = 2
76
+ LATENCY = 3
77
+ GPU = 4
78
+ ERROR_RATE = 5
79
+ THROUGHPUT = 6
80
+
81
+
82
+ class Aggregation(Enum):
83
+ NOT_VALID = 0
84
+ MIN = 1
85
+ MAX = 2
86
+ AVERAGE = 3
87
+ SUM = 4
88
+
89
+
90
+ @dataclass
91
+ class QuerySpec:
92
+ metric: Metric = field(default=None)
93
+ aggregation: Aggregation = field(default=None)
94
+ time_period: int = field(default=None)
95
+ error_code: str = field(default=None)
96
+
97
+
98
+ class Triggers(ABC):
99
+ pass
100
+
101
+
102
+ @dataclass
103
+ class PrometheusTrigger(Triggers):
104
+ query_spec: QuerySpec = field(default=None)
105
+ threshold: int = field(default=None)
106
+
107
+
108
+ @dataclass
109
+ class AutoScalingConfig:
110
+ min_replica_count: int = field(default=None)
111
+ max_replica_count: int = field(default=None)
112
+ pooling_interval: int = field(default=None)
113
+ cool_down_period: int = field(default=None)
114
+ triggers: List[Triggers] = field(default_factory=list)
115
+
116
+
117
+ @dataclass
118
+ class TrafficConfig:
119
+ selected_variation_name: str = field(default=None)
120
+ variations: List[Variation] = field(default_factory=list)
121
+ audiences: List[AudienceRoute] = field(default_factory=list)
122
+ fallback_variation: str = field(default=None)
123
+
124
+
125
+ class ServingConfig(ABC):
126
+ pass
127
+
128
+
129
+ @dataclass
130
+ class RealTimeConfig(ServingConfig):
131
+ traffic_config: TrafficConfig = field(default=None)
132
+ autoscaling_config: AutoScalingConfig = field(default=None)
133
+
134
+
135
+ @dataclass
136
+ class BatchConfig(ServingConfig):
137
+ pass
138
+
139
+
140
+ class AutoOffSet(Enum):
141
+ UNKNOWN = 0
142
+ EARLIEST = 1
143
+ LATEST = 2
144
+
145
+
146
+ @dataclass
147
+ class Consumer:
148
+ bootstrap_server: List[str] = field(default_factory=list)
149
+ topic: str = field(default=None)
150
+ group: str = field(default=None)
151
+ timeout: int = field(default=None)
152
+ auto_offset: AutoOffSet = field(default=None)
153
+ max_batch_size: int = field(default=None)
154
+ max_poll_latency: float = field(default=None)
155
+
156
+
157
+ class Compression(Enum):
158
+ UNKNOWN = 0
159
+ UNCOMPRESSED = 1
160
+ GZIP = 2
161
+ SNAPPY = 3
162
+ LZ4 = 4
163
+ ZSTD = 5
164
+
165
+
166
+ @dataclass
167
+ class Producer:
168
+ bootstrap_server: List[str] = field(default_factory=list)
169
+ topic: str = field(default=None)
170
+ compression: Compression = field(default=None)
171
+
172
+
173
+ @dataclass
174
+ class KafkaConfig:
175
+ consumer: Consumer = field(default=None)
176
+ producer: Producer = field(default=None)
177
+ workers: int = field(default=None)
178
+
179
+
180
+ @dataclass
181
+ class StreamConfig(ServingConfig):
182
+ kafka: KafkaConfig = field(default=None)
183
+
184
+
185
+ class BuildStatus(Enum):
186
+ INVALID = 0
187
+ IN_PROGRESS = 1
188
+ SUCCESSFUL = 2
189
+ FAILED = 3
190
+ REMOTE_BUILD_INITIALIZING = 4
191
+ REMOTE_BUILD_CANCELLED = 5
192
+ REMOTE_BUILD_TIMED_OUT = 6
193
+ REMOTE_BUILD_UNKNOWN = 7
194
+ SYNCING_ENVIRONMENTS = 8
195
+ FINISHED_SYNCING = 9
196
+
197
+
198
+ class MemoryUnit(Enum):
199
+ UNKNOWN = 0
200
+ MIB = 1
201
+ GIB = 2
202
+
203
+
204
+ class KubeDeploymentType(Enum):
205
+ UNDEFINED = 0
206
+ ONLINE = 1
207
+ STREAM = 2
208
+ BATCH = 3
209
+
210
+
211
+ class GpuType(Enum):
212
+ INVALID_GPU = 0
213
+ ONLINE = 1
214
+ STREAM = 2
215
+ BATCH = 3
216
+
217
+
218
+ @dataclass
219
+ class Deployment:
220
+ build_id: str = field(default=None)
221
+ number_of_pods: int = field(default=None)
222
+ cpu_fraction: float = field(default=None)
223
+ memory_amount: int = field(default=None)
224
+ memory_units: MemoryUnit = field(default=MemoryUnit.UNKNOWN)
225
+ number_of_workers: int = field(default=None)
226
+ http_request_timeout_ms: int = field(default=None)
227
+ kube_deployment_type: KubeDeploymentType = field(
228
+ default=KubeDeploymentType.UNDEFINED
229
+ )
230
+ serving_config: ServingConfig = field(default=None)
231
+ variation: Variation = field(default=None)
232
+ custom_iam_role_arn: str = field(default=None)
233
+ max_batch_size: int = field(default=None)
234
+ gpu_type: GpuType = field(default=GpuType.INVALID_GPU)
235
+ gpu_amount: int = field(default=None)
236
+ environment_id: str = field(default=None)
237
+ available_replicas: int = field(default=None)
238
+ deployment_process_timeout_limit: int = field(default=None)
239
+ daemon_mode: bool = field(default=None)
240
+ purchase_option: str = field(default=None)
241
+ environment_variables: Dict[str, str] = field(default_factory=dict)
242
+ last_deployed: datetime = field(default=datetime.now())
243
+
244
+ @staticmethod
245
+ def parse_routes(proto: List[RouteProto]) -> List[Route]:
246
+ routes = []
247
+ for proto_route in proto:
248
+ route = Route(
249
+ variation_name=proto_route.variation_name,
250
+ weight=proto_route.weight,
251
+ shadow=proto_route.shadow,
252
+ model_id=proto_route.model_id,
253
+ environment_id=proto_route.environment_id,
254
+ audience_id=proto_route.audience_id,
255
+ )
256
+ routes.append(route)
257
+ return routes
258
+
259
+ @staticmethod
260
+ def parse_audience_routes(proto: List[RouteProto]) -> List[AudienceRoute]:
261
+ routes = []
262
+ for proto_route in proto:
263
+ route = AudienceRoute(
264
+ audience_id=proto_route.audience_id,
265
+ audience_name=proto_route.audience_name,
266
+ routes=Deployment.parse_routes(proto_route.routes),
267
+ order=proto_route.order,
268
+ )
269
+ routes.append(route)
270
+ return routes
271
+
272
+ @staticmethod
273
+ def parse_autoscaling(proto: AutoScalingProto) -> AutoScalingConfig:
274
+ triggers = []
275
+ for proto_trigger in proto.triggers.triggers:
276
+ trigger = PrometheusTrigger(
277
+ query_spec=QuerySpec(
278
+ metric=Metric(
279
+ proto_trigger.prometheus_trigger.query_spec.metric_type
280
+ ),
281
+ aggregation=Aggregation(
282
+ proto_trigger.prometheus_trigger.query_spec.aggregation_type
283
+ ),
284
+ time_period=proto_trigger.prometheus_trigger.query_spec.time_period,
285
+ error_code=proto_trigger.prometheus_trigger.query_spec.error_code,
286
+ ),
287
+ threshold=proto_trigger.prometheus_trigger.threshold,
288
+ )
289
+ triggers.append(trigger)
290
+ return AutoScalingConfig(
291
+ min_replica_count=proto.min_replica_count,
292
+ max_replica_count=proto.max_replica_count,
293
+ pooling_interval=proto.polling_interval,
294
+ cool_down_period=proto.cool_down_period,
295
+ triggers=triggers,
296
+ )
297
+
298
+ @staticmethod
299
+ def parse_realtime_config(proto: RealTimeConfigProto) -> RealTimeConfig:
300
+ variations = []
301
+ for proto_variation in proto.traffic_config.variations:
302
+ variation = Variation(
303
+ name=proto_variation.name,
304
+ environment_id=proto_variation.environment_id,
305
+ traffic_spec=TrafficSpec(
306
+ percentage=proto_variation.traffic.percentage,
307
+ is_shadow=proto_variation.traffic.is_shadow,
308
+ ),
309
+ )
310
+ variations.append(variation)
311
+ audiences = []
312
+ for proto_audience in proto.traffic_config.audience_routes_entries:
313
+ audience = AudienceRoute(
314
+ audience_id=proto_audience.audience_id,
315
+ audience_name=proto_audience.audience_name,
316
+ routes=Deployment.parse_routes(proto_audience.routes),
317
+ order=proto_audience.order,
318
+ )
319
+ audiences.append(audience)
320
+
321
+ autoscaling = Deployment.parse_autoscaling(proto.auto_scaling_config)
322
+ return RealTimeConfig(
323
+ traffic_config=TrafficConfig(
324
+ variations=variations,
325
+ audiences=audiences,
326
+ fallback_variation=proto.traffic_config.fallback_variation,
327
+ ),
328
+ autoscaling_config=autoscaling,
329
+ )
330
+
331
+ @staticmethod
332
+ def parse_streaming_config(proto_config: StreamConfigProto) -> StreamConfig:
333
+ return StreamConfig(
334
+ kafka=KafkaConfig(
335
+ consumer=Consumer(
336
+ bootstrap_server=list(proto_config.kafka.consumer.bootstrap_server),
337
+ topic=proto_config.kafka.consumer.topic,
338
+ group=proto_config.kafka.consumer.group,
339
+ timeout=proto_config.kafka.consumer.timeout,
340
+ auto_offset=AutoOffSet(proto_config.kafka.consumer.auto_offset_type)
341
+ if proto_config.kafka.consumer.auto_offset_type
342
+ else None,
343
+ max_batch_size=proto_config.kafka.consumer.max_batch_size,
344
+ max_poll_latency=proto_config.kafka.consumer.max_poll_latency,
345
+ ),
346
+ producer=Producer(
347
+ bootstrap_server=list(proto_config.kafka.producer.bootstrap_server),
348
+ topic=proto_config.kafka.producer.topic,
349
+ compression=Compression(
350
+ proto_config.kafka.producer.compression_type
351
+ )
352
+ if proto_config.kafka.producer.compression_type
353
+ else None,
354
+ ),
355
+ workers=proto_config.kafka.workers,
356
+ )
357
+ )
358
+
359
+ @staticmethod
360
+ def parse_serving_strategy(proto: ServingStrategyProto) -> ServingConfig:
361
+ which = proto.WhichOneof("Strategy")
362
+ if which == "realtime_config":
363
+ return Deployment.parse_realtime_config(proto.realtime_config)
364
+ elif which == "batch_config":
365
+ return BatchConfig()
366
+ elif which == "stream_config":
367
+ return Deployment.parse_streaming_config(proto.stream_config)
368
+ else:
369
+ raise ValueError(f"Unknown serving strategy: {which}")
370
+
371
+ @staticmethod
372
+ def from_proto(proto: DeploymentProto):
373
+ variation = Variation(
374
+ name=proto.variation.name,
375
+ environment_id=proto.variation.environment_id,
376
+ traffic_spec=TrafficSpec(
377
+ percentage=proto.variation.traffic.percentage,
378
+ is_shadow=proto.variation.traffic.is_shadow,
379
+ ),
380
+ )
381
+ return Deployment(
382
+ build_id=proto.build_id,
383
+ number_of_pods=proto.number_of_pods,
384
+ cpu_fraction=proto.cpu_fraction,
385
+ memory_amount=proto.memory_amount,
386
+ memory_units=MemoryUnit(proto.memory_units),
387
+ number_of_workers=proto.number_of_workers,
388
+ http_request_timeout_ms=proto.http_request_timeout_ms,
389
+ kube_deployment_type=KubeDeploymentType(proto.kube_deployment_type),
390
+ serving_config=Deployment.parse_serving_strategy(proto.serving_strategy),
391
+ variation=variation,
392
+ custom_iam_role_arn=proto.custom_iam_role_arn,
393
+ max_batch_size=proto.max_batch_size,
394
+ gpu_type=GpuType(proto.gpu_type),
395
+ gpu_amount=proto.gpu_amount,
396
+ environment_id=proto.environment_id,
397
+ available_replicas=proto.available_replicas,
398
+ daemon_mode=bool(proto.daemon_mode.value),
399
+ deployment_process_timeout_limit=proto.deployment_process_timeout_limit,
400
+ purchase_option=proto.purchase_option,
401
+ environment_variables=dict(proto.environment_variables),
402
+ last_deployed=datetime.fromtimestamp(
403
+ proto.last_deployed.seconds + proto.last_deployed.nanos / 1e9
404
+ ),
405
+ )
@@ -0,0 +1,114 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Dict
4
+
5
+ from _qwak_proto.qwak.deployment.deployment_pb2 import (
6
+ BatchConfig,
7
+ EnvironmentDeploymentMessage,
8
+ HostingService,
9
+ KubeDeployment,
10
+ KubeDeploymentType,
11
+ ServingStrategy,
12
+ )
13
+ from qwak.clients.administration.eco_system.client import EcosystemClient
14
+ from qwak.clients.instance_template.client import InstanceTemplateManagementClient
15
+ from qwak.exceptions import QwakException
16
+
17
+ from qwak_sdk.commands.models.deployments.deploy._logic.advance_deployment_options_handler import (
18
+ get_advanced_deployment_options_from_deploy_config,
19
+ )
20
+ from qwak_sdk.commands.models.deployments.deploy._logic.deploy_config import (
21
+ DeployConfig,
22
+ )
23
+ from qwak_sdk.commands.models.deployments.deploy._logic.deployment_size_mapper import (
24
+ deployment_size_from_deploy_config,
25
+ )
26
+ from qwak_sdk.commands.models.deployments.deploy.realtime._logic.serving_strategy_mapper import (
27
+ create_realtime_serving_strategy_from_deploy_config,
28
+ )
29
+ from qwak_sdk.commands.models.deployments.deploy.streaming._logic.serving_strategy_mapper import (
30
+ create_streaming_serving_strategy_from_deploy_config,
31
+ )
32
+ from qwak_sdk.inner.tools.cli_tools import dictify_params
33
+
34
+ UNKNOWN_SERVING_STRATEGY = (
35
+ "The deployments type doesn't have a serving strategy configured"
36
+ )
37
+
38
+
39
+ def get_env_to_deployment_message(
40
+ deploy_config: DeployConfig,
41
+ kube_deployment_type: KubeDeploymentType,
42
+ ecosystem_client: EcosystemClient,
43
+ instance_template_client: InstanceTemplateManagementClient,
44
+ ) -> Dict[str, EnvironmentDeploymentMessage]:
45
+ deployment_size = deployment_size_from_deploy_config(
46
+ deploy_config, instance_template_client, ecosystem_client
47
+ )
48
+ advanced_deployment_options = get_advanced_deployment_options_from_deploy_config(
49
+ deploy_config, kube_deployment_type
50
+ )
51
+ environment_variables = {}
52
+
53
+ if len(deploy_config.realtime.environments) != 0:
54
+ deploy_config.environments = deploy_config.realtime.environments
55
+
56
+ environment_name_to_config = ecosystem_client.get_environments_names_to_details(
57
+ deploy_config.environments
58
+ )
59
+
60
+ if kube_deployment_type == KubeDeploymentType.ONLINE:
61
+ env_to_serving_strategy = create_realtime_serving_strategy_from_deploy_config(
62
+ deploy_config,
63
+ environment_name_to_config,
64
+ )
65
+ environment_variables = dictify_params(deploy_config.realtime.env_vars)
66
+ elif kube_deployment_type == KubeDeploymentType.BATCH:
67
+ env_to_serving_strategy = {}
68
+ if len(environment_name_to_config) == 0:
69
+ env_to_serving_strategy = {
70
+ ecosystem_client.get_account_details().default_environment_id: ServingStrategy(
71
+ batch_config=BatchConfig()
72
+ )
73
+ }
74
+ else:
75
+ for env_name, env_config in environment_name_to_config.items():
76
+ env_to_serving_strategy[env_config.id] = ServingStrategy(
77
+ batch_config=BatchConfig()
78
+ )
79
+
80
+ elif kube_deployment_type == KubeDeploymentType.STREAM:
81
+ env_to_serving_strategy = {}
82
+ if len(environment_name_to_config) == 0:
83
+ env_to_serving_strategy[
84
+ ecosystem_client.get_account_details().default_environment_id
85
+ ] = create_streaming_serving_strategy_from_deploy_config(deploy_config)
86
+ else:
87
+ for env_name, env_config in environment_name_to_config.items():
88
+ env_to_serving_strategy[
89
+ env_config.id
90
+ ] = create_streaming_serving_strategy_from_deploy_config(deploy_config)
91
+ environment_variables = dictify_params(deploy_config.stream.env_vars)
92
+ else:
93
+ raise QwakException(UNKNOWN_SERVING_STRATEGY)
94
+ env_to_hosting_services = {
95
+ env_id: HostingService(
96
+ kube_deployment=KubeDeployment(
97
+ deployment_size=deployment_size,
98
+ advanced_deployment_options=advanced_deployment_options,
99
+ serving_strategy=serving_strategy,
100
+ kube_deployment_type=kube_deployment_type,
101
+ environment_variables=environment_variables,
102
+ ),
103
+ )
104
+ for env_id, serving_strategy in env_to_serving_strategy.items()
105
+ }
106
+ env_deployment_messages = {
107
+ env_id: EnvironmentDeploymentMessage(
108
+ model_id=deploy_config.model_id,
109
+ build_id=deploy_config.build_id,
110
+ hosting_service=hosting_service,
111
+ )
112
+ for env_id, hosting_service in env_to_hosting_services.items()
113
+ }
114
+ return env_deployment_messages
@@ -0,0 +1,156 @@
1
+ from typing import Dict
2
+
3
+ from _qwak_proto.qwak.deployment.deployment_pb2 import ModelDeploymentStatus
4
+ from _qwak_proto.qwak.deployment.deployment_service_pb2 import DeployModelResponse
5
+ from _qwak_proto.qwak.ecosystem.v0.ecosystem_pb2 import UserContextEnvironmentDetails
6
+ from qwak.clients.administration.eco_system.client import EcosystemClient
7
+ from qwak.exceptions import QwakException
8
+ from qwak.tools.logger.logger import get_qwak_logger
9
+ from tabulate import tabulate
10
+
11
+ from qwak_sdk.commands.models.deployments.deploy._logic.base_deploy_executor import (
12
+ FAILED_STATUS,
13
+ BaseDeployExecutor,
14
+ )
15
+ from qwak_sdk.tools.utils import qwak_spinner
16
+
17
+ logger = get_qwak_logger()
18
+
19
+
20
+ def __client_deployment_remote(
21
+ deploy: BaseDeployExecutor, sync: bool, output_multiple: bool = False
22
+ ):
23
+ try:
24
+ deploy_response: DeployModelResponse = deploy.deploy()
25
+ deploy_status, deploy_id = (
26
+ ModelDeploymentStatus.Name(deploy_response.status),
27
+ deploy_response.deployment_named_id,
28
+ )
29
+
30
+ if deploy_response.environment_to_deployment_result:
31
+ account_environments = EcosystemClient().get_environments()
32
+ output_deployments_response(account_environments, deploy, deploy_response)
33
+ __check_failed_deployments(account_environments, deploy_response)
34
+
35
+ if sync:
36
+ deployment_id_to_env = {}
37
+ for (
38
+ env_id,
39
+ env_deploy_response,
40
+ ) in deploy_response.environment_to_deployment_result.items():
41
+ deployment_id_to_env[
42
+ env_deploy_response.deployment_named_id
43
+ ] = account_environments.get(env_id).name
44
+
45
+ __sync_deployments(deploy, deployment_id_to_env)
46
+
47
+ if output_multiple:
48
+ return deploy_response.environment_to_deployment_result
49
+ else:
50
+ if "FAILED" in deploy_status:
51
+ raise QwakException(deploy_response.info)
52
+
53
+ if sync:
54
+ __sync_deployment(deploy, deploy_id)
55
+
56
+ if not sync:
57
+ logger.info(
58
+ "Deployment initiated successfully, Use --sync to wait for deployments to be ready."
59
+ )
60
+ return deploy_id, deploy_status
61
+ except Exception as e:
62
+ logger.error(f"Deployment failed, Error: {e}")
63
+ raise e
64
+
65
+
66
+ def __check_failed_deployments(
67
+ account_environments: Dict[str, UserContextEnvironmentDetails],
68
+ deploy_response: DeployModelResponse,
69
+ ):
70
+ failed_deployments = {}
71
+ for (
72
+ env_id,
73
+ env_deploy_response,
74
+ ) in deploy_response.environment_to_deployment_result.items():
75
+ deploy_status = ModelDeploymentStatus.Name(env_deploy_response.status)
76
+ if "FAILED" in deploy_status:
77
+ env_config = account_environments.get(env_id)
78
+ failed_deployments[
79
+ env_config.name if env_config else env_id
80
+ ] = env_deploy_response.info
81
+ if failed_deployments:
82
+ failed_deployments_message = "\n".join(
83
+ [
84
+ f"Environment {env_name}: {reason}"
85
+ for env_name, reason in failed_deployments.items()
86
+ ]
87
+ )
88
+ raise QwakException(
89
+ f"The following deployments failed:\n {failed_deployments_message}"
90
+ )
91
+
92
+
93
+ def output_deployments_response(
94
+ account_environments: Dict[str, UserContextEnvironmentDetails],
95
+ deploy: BaseDeployExecutor,
96
+ deploy_response: DeployModelResponse,
97
+ ):
98
+ for (
99
+ env_id,
100
+ env_deploy_response,
101
+ ) in deploy_response.environment_to_deployment_result.items():
102
+ env_config = account_environments.get(env_id)
103
+ if env_deploy_response.status == ModelDeploymentStatus.INITIATING_DEPLOYMENT:
104
+ logger.info(
105
+ tabulate(
106
+ tabular_data=[
107
+ ["Environment", env_config.name],
108
+ ["Model ID", deploy.config.model_id],
109
+ ["Build ID", deploy.config.build_id],
110
+ ["Deployment ID", env_deploy_response.deployment_named_id],
111
+ ],
112
+ tablefmt="fancy_grid",
113
+ )
114
+ )
115
+
116
+
117
+ def __sync_deployments(
118
+ deploy: BaseDeployExecutor, deployment_id_to_env: Dict[str, str]
119
+ ):
120
+ with qwak_spinner(
121
+ begin_text=f"Deploy - model: {deploy.config.model_id}, build: {deploy.config.build_id} "
122
+ f"Environments: {', '.join(deploy.config.realtime.environments)}",
123
+ end_text="Successful deployments",
124
+ print_callback=print,
125
+ ):
126
+ deployment_id_to_status = deploy.poll_until_complete_multiple(
127
+ list(deployment_id_to_env.keys()), check_every_n_seconds=5
128
+ )
129
+ failed_deployments = []
130
+ for deployment_id, status in deployment_id_to_status.items():
131
+ if status in FAILED_STATUS:
132
+ failed_deployments.append(
133
+ f"Environment {deployment_id_to_env.get(deployment_id)} "
134
+ f"failed with status: {status}"
135
+ )
136
+ if failed_deployments:
137
+ raise QwakException("\n".join(failed_deployments))
138
+
139
+
140
+ def __sync_deployment(deploy: BaseDeployExecutor, deploy_name: str):
141
+ with qwak_spinner(
142
+ begin_text=f"Deploy - model: {deploy.config.model_id}, build: {deploy.config.build_id}",
143
+ end_text="Successful deployments",
144
+ print_callback=print,
145
+ ):
146
+ deployment_status = deploy.poll_until_complete(
147
+ deploy_name, check_every_n_seconds=5
148
+ )
149
+ if deployment_status in FAILED_STATUS:
150
+ raise QwakException(deployment_status)
151
+
152
+
153
+ def client_deployment(
154
+ deploy: BaseDeployExecutor, sync: bool, output_multiple: bool = False
155
+ ):
156
+ return __client_deployment_remote(deploy, sync, output_multiple)