frogml-cli 0.0.1__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 (287) hide show
  1. frogml_cli/__init__.py +10 -0
  2. frogml_cli/cli.py +40 -0
  3. frogml_cli/commands/__init__.py +0 -0
  4. frogml_cli/commands/_logic/__init__.py +0 -0
  5. frogml_cli/commands/_logic/tools.py +6 -0
  6. frogml_cli/commands/alerts/__init__.py +0 -0
  7. frogml_cli/commands/alerts/alerts_commnad_group.py +18 -0
  8. frogml_cli/commands/alerts/delete/__init__.py +0 -0
  9. frogml_cli/commands/alerts/delete/_logic.py +5 -0
  10. frogml_cli/commands/alerts/delete/ui.py +10 -0
  11. frogml_cli/commands/alerts/list/__init__.py +0 -0
  12. frogml_cli/commands/alerts/list/_logic.py +23 -0
  13. frogml_cli/commands/alerts/list/ui.py +17 -0
  14. frogml_cli/commands/alerts/register/__init__.py +0 -0
  15. frogml_cli/commands/alerts/register/_logic.py +72 -0
  16. frogml_cli/commands/alerts/register/ui.py +30 -0
  17. frogml_cli/commands/audience/__init__.py +0 -0
  18. frogml_cli/commands/audience/_logic/__init__.py +0 -0
  19. frogml_cli/commands/audience/_logic/config/__init__.py +0 -0
  20. frogml_cli/commands/audience/_logic/config/config_base.py +15 -0
  21. frogml_cli/commands/audience/_logic/config/parser.py +30 -0
  22. frogml_cli/commands/audience/_logic/config/v1/__init__.py +0 -0
  23. frogml_cli/commands/audience/_logic/config/v1/audience_config.py +25 -0
  24. frogml_cli/commands/audience/_logic/config/v1/conditions_config.py +59 -0
  25. frogml_cli/commands/audience/_logic/config/v1/config_v1.py +23 -0
  26. frogml_cli/commands/audience/_logic/config/v1/route_config.py +15 -0
  27. frogml_cli/commands/audience/_logic/config/v1/spec.py +9 -0
  28. frogml_cli/commands/audience/audience_api_dump.py +86 -0
  29. frogml_cli/commands/audience/audience_commands_group.py +30 -0
  30. frogml_cli/commands/audience/create/__init__.py +0 -0
  31. frogml_cli/commands/audience/create/logic.py +41 -0
  32. frogml_cli/commands/audience/create/ui.py +21 -0
  33. frogml_cli/commands/audience/delete/__init__.py +0 -0
  34. frogml_cli/commands/audience/delete/logic.py +13 -0
  35. frogml_cli/commands/audience/delete/ui.py +17 -0
  36. frogml_cli/commands/audience/get/__init__.py +0 -0
  37. frogml_cli/commands/audience/get/logic.py +14 -0
  38. frogml_cli/commands/audience/get/ui.py +25 -0
  39. frogml_cli/commands/audience/list/__init__.py +0 -0
  40. frogml_cli/commands/audience/list/logic.py +16 -0
  41. frogml_cli/commands/audience/list/ui.py +26 -0
  42. frogml_cli/commands/audience/update/__init__.py +0 -0
  43. frogml_cli/commands/audience/update/logic.py +37 -0
  44. frogml_cli/commands/audience/update/ui.py +26 -0
  45. frogml_cli/commands/auto_scalling/__init__.py +0 -0
  46. frogml_cli/commands/auto_scalling/_logic/__init__.py +0 -0
  47. frogml_cli/commands/auto_scalling/_logic/config/__init__.py +3 -0
  48. frogml_cli/commands/auto_scalling/_logic/config/config.py +152 -0
  49. frogml_cli/commands/auto_scalling/_logic/config/parser.py +21 -0
  50. frogml_cli/commands/auto_scalling/attach/__init__.py +0 -0
  51. frogml_cli/commands/auto_scalling/attach/_logic.py +43 -0
  52. frogml_cli/commands/auto_scalling/attach/ui.py +21 -0
  53. frogml_cli/commands/auto_scalling/autoscaling_commands_group.py +15 -0
  54. frogml_cli/commands/automations/__init__.py +0 -0
  55. frogml_cli/commands/automations/automations_commands_group.py +30 -0
  56. frogml_cli/commands/automations/delete/__init__.py +0 -0
  57. frogml_cli/commands/automations/delete/_logic.py +6 -0
  58. frogml_cli/commands/automations/delete/ui.py +23 -0
  59. frogml_cli/commands/automations/executions/__init__.py +0 -0
  60. frogml_cli/commands/automations/executions/executions_commands_group.py +14 -0
  61. frogml_cli/commands/automations/executions/list/__init__.py +0 -0
  62. frogml_cli/commands/automations/executions/list/_logic.py +8 -0
  63. frogml_cli/commands/automations/executions/list/ui.py +27 -0
  64. frogml_cli/commands/automations/list/__init__.py +0 -0
  65. frogml_cli/commands/automations/list/_logic.py +36 -0
  66. frogml_cli/commands/automations/list/ui.py +21 -0
  67. frogml_cli/commands/automations/register/__init__.py +0 -0
  68. frogml_cli/commands/automations/register/_logic.py +43 -0
  69. frogml_cli/commands/automations/register/ui.py +44 -0
  70. frogml_cli/commands/config/__init__.py +0 -0
  71. frogml_cli/commands/config/add/__init__.py +0 -0
  72. frogml_cli/commands/config/add/ui.py +62 -0
  73. frogml_cli/commands/config/config_commands_group.py +11 -0
  74. frogml_cli/commands/feature_store/__init__.py +0 -0
  75. frogml_cli/commands/feature_store/backfill/__init__.py +0 -0
  76. frogml_cli/commands/feature_store/backfill/_logic.py +140 -0
  77. frogml_cli/commands/feature_store/backfill/ui.py +129 -0
  78. frogml_cli/commands/feature_store/delete/__init__.py +0 -0
  79. frogml_cli/commands/feature_store/delete/_logic.py +107 -0
  80. frogml_cli/commands/feature_store/delete/ui.py +40 -0
  81. frogml_cli/commands/feature_store/execution/__init__.py +0 -0
  82. frogml_cli/commands/feature_store/execution/ui.py +19 -0
  83. frogml_cli/commands/feature_store/feature_store_command_group.py +29 -0
  84. frogml_cli/commands/feature_store/list/__init__.py +0 -0
  85. frogml_cli/commands/feature_store/list/ui.py +140 -0
  86. frogml_cli/commands/feature_store/pause/__init__.py +0 -0
  87. frogml_cli/commands/feature_store/pause/ui.py +18 -0
  88. frogml_cli/commands/feature_store/register/__init__.py +0 -0
  89. frogml_cli/commands/feature_store/register/_logic.py +369 -0
  90. frogml_cli/commands/feature_store/register/ui.py +111 -0
  91. frogml_cli/commands/feature_store/resume/__init__.py +0 -0
  92. frogml_cli/commands/feature_store/resume/ui.py +18 -0
  93. frogml_cli/commands/feature_store/trigger/__init__.py +0 -0
  94. frogml_cli/commands/feature_store/trigger/ui.py +39 -0
  95. frogml_cli/commands/models/__init__.py +0 -0
  96. frogml_cli/commands/models/build/__init__.py +0 -0
  97. frogml_cli/commands/models/build/_logic/__init__.py +0 -0
  98. frogml_cli/commands/models/build/_logic/build_steps.py +42 -0
  99. frogml_cli/commands/models/build/_logic/client_logs/__init__.py +0 -0
  100. frogml_cli/commands/models/build/_logic/client_logs/cli_phase_run_handler.py +123 -0
  101. frogml_cli/commands/models/build/_logic/client_logs/cli_trigger_build_logger.py +19 -0
  102. frogml_cli/commands/models/build/_logic/client_logs/logger.py +88 -0
  103. frogml_cli/commands/models/build/_logic/client_logs/messages.py +36 -0
  104. frogml_cli/commands/models/build/_logic/client_logs/spinner.py +14 -0
  105. frogml_cli/commands/models/build/_logic/client_logs/trigger_build_logger.py +54 -0
  106. frogml_cli/commands/models/build/_logic/client_logs/utils.py +12 -0
  107. frogml_cli/commands/models/build/_logic/phase/__init__.py +0 -0
  108. frogml_cli/commands/models/build/_logic/phase/a_fetch_model_code/__init__.py +20 -0
  109. frogml_cli/commands/models/build/_logic/phase/a_fetch_model_code/get_sdk_version_step.py +15 -0
  110. frogml_cli/commands/models/build/_logic/phase/b_remote_register_frogml_build/__init__.py +16 -0
  111. frogml_cli/commands/models/build/_logic/phase/c_deploy/__init__.py +6 -0
  112. frogml_cli/commands/models/build/_logic/phase/c_deploy/build_polling_status.py +55 -0
  113. frogml_cli/commands/models/build/_logic/phase/c_deploy/deploy_build.py +61 -0
  114. frogml_cli/commands/models/build/_logic/util/__init__.py +0 -0
  115. frogml_cli/commands/models/build/_logic/util/protobuf_factory.py +45 -0
  116. frogml_cli/commands/models/build/_logic/util/step_decorator.py +60 -0
  117. frogml_cli/commands/models/build/_logic/util/text.py +9 -0
  118. frogml_cli/commands/models/build/_logic/wait_until_finished.py +27 -0
  119. frogml_cli/commands/models/build/ui.py +337 -0
  120. frogml_cli/commands/models/builds/__init__.py +0 -0
  121. frogml_cli/commands/models/builds/builds_commands_group.py +16 -0
  122. frogml_cli/commands/models/builds/cancel/__init__.py +0 -0
  123. frogml_cli/commands/models/builds/cancel/_logic.py +5 -0
  124. frogml_cli/commands/models/builds/cancel/ui.py +15 -0
  125. frogml_cli/commands/models/builds/logs/__init__.py +0 -0
  126. frogml_cli/commands/models/builds/logs/ui.py +35 -0
  127. frogml_cli/commands/models/builds/status/__init__.py +0 -0
  128. frogml_cli/commands/models/builds/status/_logic.py +6 -0
  129. frogml_cli/commands/models/builds/status/ui.py +39 -0
  130. frogml_cli/commands/models/create/__init__.py +0 -0
  131. frogml_cli/commands/models/create/_logic.py +40 -0
  132. frogml_cli/commands/models/create/ui.py +46 -0
  133. frogml_cli/commands/models/delete/__init__.py +0 -0
  134. frogml_cli/commands/models/delete/_logic.py +18 -0
  135. frogml_cli/commands/models/delete/ui.py +25 -0
  136. frogml_cli/commands/models/deployments/__init__.py +0 -0
  137. frogml_cli/commands/models/deployments/deploy/__init__.py +0 -0
  138. frogml_cli/commands/models/deployments/deploy/_logic/__init__.py +0 -0
  139. frogml_cli/commands/models/deployments/deploy/_logic/advance_deployment_options_handler.py +31 -0
  140. frogml_cli/commands/models/deployments/deploy/_logic/base_deploy_executor.py +70 -0
  141. frogml_cli/commands/models/deployments/deploy/_logic/deploy_config.py +261 -0
  142. frogml_cli/commands/models/deployments/deploy/_logic/deployment.py +407 -0
  143. frogml_cli/commands/models/deployments/deploy/_logic/deployment_message_helpers.py +116 -0
  144. frogml_cli/commands/models/deployments/deploy/_logic/deployment_response_handler.py +156 -0
  145. frogml_cli/commands/models/deployments/deploy/_logic/deployment_size_mapper.py +98 -0
  146. frogml_cli/commands/models/deployments/deploy/_logic/get_latest_successful_build.py +28 -0
  147. frogml_cli/commands/models/deployments/deploy/_logic/local_deployment.py +193 -0
  148. frogml_cli/commands/models/deployments/deploy/batch/__init__.py +0 -0
  149. frogml_cli/commands/models/deployments/deploy/batch/_logic/__init__.py +0 -0
  150. frogml_cli/commands/models/deployments/deploy/batch/_logic/advanced_deployment_mapper.py +15 -0
  151. frogml_cli/commands/models/deployments/deploy/batch/_logic/deploy_executor.py +24 -0
  152. frogml_cli/commands/models/deployments/deploy/batch/ui.py +119 -0
  153. frogml_cli/commands/models/deployments/deploy/deploy_commands_group.py +19 -0
  154. frogml_cli/commands/models/deployments/deploy/realtime/__init__.py +0 -0
  155. frogml_cli/commands/models/deployments/deploy/realtime/_logic/__init__.py +0 -0
  156. frogml_cli/commands/models/deployments/deploy/realtime/_logic/advanced_deployment_mapper.py +21 -0
  157. frogml_cli/commands/models/deployments/deploy/realtime/_logic/deploy_executor.py +24 -0
  158. frogml_cli/commands/models/deployments/deploy/realtime/_logic/serving_strategy_mapper.py +75 -0
  159. frogml_cli/commands/models/deployments/deploy/realtime/ui.py +202 -0
  160. frogml_cli/commands/models/deployments/deploy/streaming/__init__.py +0 -0
  161. frogml_cli/commands/models/deployments/deploy/streaming/_logic/__init__.py +0 -0
  162. frogml_cli/commands/models/deployments/deploy/streaming/_logic/deploy_executor.py +24 -0
  163. frogml_cli/commands/models/deployments/deploy/streaming/_logic/serving_strategy_mapper.py +38 -0
  164. frogml_cli/commands/models/deployments/deploy/streaming/ui.py +206 -0
  165. frogml_cli/commands/models/deployments/undeploy/__init__.py +0 -0
  166. frogml_cli/commands/models/deployments/undeploy/_logic/__init__.py +0 -0
  167. frogml_cli/commands/models/deployments/undeploy/_logic/request_undeploy.py +249 -0
  168. frogml_cli/commands/models/deployments/undeploy/ui.py +61 -0
  169. frogml_cli/commands/models/describe/__init__.py +0 -0
  170. frogml_cli/commands/models/describe/_logic.py +169 -0
  171. frogml_cli/commands/models/describe/ui.py +35 -0
  172. frogml_cli/commands/models/executions/__init__.py +0 -0
  173. frogml_cli/commands/models/executions/cancel/__init__.py +0 -0
  174. frogml_cli/commands/models/executions/cancel/_logic.py +9 -0
  175. frogml_cli/commands/models/executions/cancel/ui.py +27 -0
  176. frogml_cli/commands/models/executions/execution_commands_group.py +24 -0
  177. frogml_cli/commands/models/executions/report/__init__.py +0 -0
  178. frogml_cli/commands/models/executions/report/_logic.py +14 -0
  179. frogml_cli/commands/models/executions/report/ui.py +43 -0
  180. frogml_cli/commands/models/executions/start/__init__.py +0 -0
  181. frogml_cli/commands/models/executions/start/_logic.py +83 -0
  182. frogml_cli/commands/models/executions/start/ui.py +208 -0
  183. frogml_cli/commands/models/executions/status/__init__.py +0 -0
  184. frogml_cli/commands/models/executions/status/_logic.py +13 -0
  185. frogml_cli/commands/models/executions/status/ui.py +27 -0
  186. frogml_cli/commands/models/init/__init__.py +0 -0
  187. frogml_cli/commands/models/init/_logic/__init__.py +0 -0
  188. frogml_cli/commands/models/init/_logic/initialize_model_structure.py +40 -0
  189. frogml_cli/commands/models/init/_logic/template/__init__.py +0 -0
  190. frogml_cli/commands/models/init/_logic/template/churn/__init__.py +0 -0
  191. frogml_cli/commands/models/init/_logic/template/churn/cookiecutter.json +3 -0
  192. frogml_cli/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/__init__.py +0 -0
  193. frogml_cli/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/main/__init__.py +5 -0
  194. frogml_cli/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/main/conda.yml +10 -0
  195. frogml_cli/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/main/data.csv +1001 -0
  196. frogml_cli/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/main/model.py +99 -0
  197. frogml_cli/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/tests/__init__.py +0 -0
  198. frogml_cli/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/tests/it/__init__.py +0 -0
  199. frogml_cli/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/tests/it/test_churn.py +32 -0
  200. frogml_cli/commands/models/init/_logic/template/credit_risk/__init__.py +0 -0
  201. frogml_cli/commands/models/init/_logic/template/credit_risk/cookiecutter.json +3 -0
  202. frogml_cli/commands/models/init/_logic/template/credit_risk/{{cookiecutter.model_directory}}/__init__.py +0 -0
  203. frogml_cli/commands/models/init/_logic/template/credit_risk/{{cookiecutter.model_directory}}/main/__init__.py +5 -0
  204. frogml_cli/commands/models/init/_logic/template/credit_risk/{{cookiecutter.model_directory}}/main/conda.yml +11 -0
  205. frogml_cli/commands/models/init/_logic/template/credit_risk/{{cookiecutter.model_directory}}/main/data.csv +1001 -0
  206. frogml_cli/commands/models/init/_logic/template/credit_risk/{{cookiecutter.model_directory}}/main/model.py +108 -0
  207. frogml_cli/commands/models/init/_logic/template/general/__init__.py +0 -0
  208. frogml_cli/commands/models/init/_logic/template/general/cookiecutter.json +6 -0
  209. frogml_cli/commands/models/init/_logic/template/general/{{cookiecutter.model_directory}}/__init__.py +0 -0
  210. frogml_cli/commands/models/init/_logic/template/general/{{cookiecutter.model_directory}}/{{cookiecutter.main_directory}}/__init__.py +5 -0
  211. frogml_cli/commands/models/init/_logic/template/general/{{cookiecutter.model_directory}}/{{cookiecutter.main_directory}}/conda.yml +8 -0
  212. frogml_cli/commands/models/init/_logic/template/general/{{cookiecutter.model_directory}}/{{cookiecutter.main_directory}}/model.py +66 -0
  213. frogml_cli/commands/models/init/_logic/template/general/{{cookiecutter.model_directory}}/{{cookiecutter.test_directory}}/__init__.py +0 -0
  214. frogml_cli/commands/models/init/_logic/template/general/{{cookiecutter.model_directory}}/{{cookiecutter.test_directory}}/test_qwak_model.py +5 -0
  215. frogml_cli/commands/models/init/_logic/template/titanic/__init__.py +0 -0
  216. frogml_cli/commands/models/init/_logic/template/titanic/cookiecutter.json +3 -0
  217. frogml_cli/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/__init__.py +0 -0
  218. frogml_cli/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/main/__init__.py +5 -0
  219. frogml_cli/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/main/conda.yml +11 -0
  220. frogml_cli/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/main/model.py +98 -0
  221. frogml_cli/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/tests/__init__.py +0 -0
  222. frogml_cli/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/tests/it/__init__.py +0 -0
  223. frogml_cli/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/tests/it/test_titanic.py +24 -0
  224. frogml_cli/commands/models/init/_logic/template/titanic_poetry/__init__.py +0 -0
  225. frogml_cli/commands/models/init/_logic/template/titanic_poetry/cookiecutter.json +3 -0
  226. frogml_cli/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/__init__.py +0 -0
  227. frogml_cli/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/main/__init__.py +5 -0
  228. frogml_cli/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/main/model.py +98 -0
  229. frogml_cli/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/main/pyproject.toml +20 -0
  230. frogml_cli/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/tests/__init__.py +0 -0
  231. frogml_cli/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/tests/it/__init__.py +0 -0
  232. frogml_cli/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/tests/it/test_titanic.py +25 -0
  233. frogml_cli/commands/models/init/ui.py +61 -0
  234. frogml_cli/commands/models/list/__init__.py +0 -0
  235. frogml_cli/commands/models/list/_logic.py +5 -0
  236. frogml_cli/commands/models/list/ui.py +41 -0
  237. frogml_cli/commands/models/list_models/__init__.py +0 -0
  238. frogml_cli/commands/models/list_models/_logic.py +11 -0
  239. frogml_cli/commands/models/list_models/ui.py +60 -0
  240. frogml_cli/commands/models/metadata/__init__.py +0 -0
  241. frogml_cli/commands/models/metadata/_logic.py +12 -0
  242. frogml_cli/commands/models/metadata/ui.py +60 -0
  243. frogml_cli/commands/models/models_command_group.py +44 -0
  244. frogml_cli/commands/models/runtime/__init__.py +0 -0
  245. frogml_cli/commands/models/runtime/logs/__init__.py +0 -0
  246. frogml_cli/commands/models/runtime/logs/ui.py +63 -0
  247. frogml_cli/commands/models/runtime/runtime_commands_group.py +17 -0
  248. frogml_cli/commands/models/runtime/update/__init__.py +0 -0
  249. frogml_cli/commands/models/runtime/update/_logic.py +9 -0
  250. frogml_cli/commands/models/runtime/update/ui.py +17 -0
  251. frogml_cli/commands/secrets/__init__.py +0 -0
  252. frogml_cli/commands/secrets/delete/__init__.py +0 -0
  253. frogml_cli/commands/secrets/delete/_logic.py +5 -0
  254. frogml_cli/commands/secrets/delete/ui.py +21 -0
  255. frogml_cli/commands/secrets/get/__init__.py +0 -0
  256. frogml_cli/commands/secrets/get/_logic.py +5 -0
  257. frogml_cli/commands/secrets/get/ui.py +17 -0
  258. frogml_cli/commands/secrets/secrets_commands_group.py +19 -0
  259. frogml_cli/commands/secrets/set/__init__.py +0 -0
  260. frogml_cli/commands/secrets/set/_logic.py +5 -0
  261. frogml_cli/commands/secrets/set/ui.py +16 -0
  262. frogml_cli/commands/ui_tools.py +18 -0
  263. frogml_cli/exceptions/__init__.py +14 -0
  264. frogml_cli/exceptions/frogml_command_exception.py +2 -0
  265. frogml_cli/exceptions/frogml_deploy_new_build_failed.py +5 -0
  266. frogml_cli/exceptions/frogml_resource_not_found.py +2 -0
  267. frogml_cli/inner/__init__.py +0 -0
  268. frogml_cli/inner/file_registry.py +98 -0
  269. frogml_cli/inner/tools/__init__.py +0 -0
  270. frogml_cli/inner/tools/cli_tools.py +179 -0
  271. frogml_cli/inner/tools/config_handler.py +29 -0
  272. frogml_cli/inner/tools/dataclasses_utils.py +21 -0
  273. frogml_cli/inner/tools/logger/__init__.py +3 -0
  274. frogml_cli/inner/tools/logger/logger.py +278 -0
  275. frogml_cli/inner/tools/logger/logging.yml +79 -0
  276. frogml_cli/inner/tools/tracking.py +47 -0
  277. frogml_cli/main.py +9 -0
  278. frogml_cli/tools/__init__.py +0 -0
  279. frogml_cli/tools/colors.py +13 -0
  280. frogml_cli/tools/const.py +3 -0
  281. frogml_cli/tools/files.py +63 -0
  282. frogml_cli/tools/log_handling.py +159 -0
  283. frogml_cli/tools/utils.py +45 -0
  284. frogml_cli-0.0.1.dist-info/METADATA +51 -0
  285. frogml_cli-0.0.1.dist-info/RECORD +287 -0
  286. frogml_cli-0.0.1.dist-info/WHEEL +4 -0
  287. frogml_cli-0.0.1.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,39 @@
1
+ import click
2
+ from frogml._proto.qwak.feature_store.features.feature_set_service_pb2 import (
3
+ RunBatchFeatureSetResponse,
4
+ )
5
+ from frogml.core.clients.feature_store import FeatureRegistryClient
6
+ from frogml.core.exceptions import FrogmlException
7
+
8
+ from frogml_cli.inner.tools.cli_tools import FrogMLCommand
9
+ from frogml_cli.tools.colors import Color
10
+
11
+
12
+ @click.command(
13
+ "trigger", cls=FrogMLCommand, help="Trigger a batch feature set job ingestion job"
14
+ )
15
+ @click.argument("name")
16
+ def trigger_feature_set(name, **kwargs):
17
+ """
18
+ Trigger a batch feature set ingestion job
19
+
20
+ Args:
21
+ name: Feature set name that will be triggered.
22
+ """
23
+ try:
24
+ result: RunBatchFeatureSetResponse = FeatureRegistryClient().run_feature_set(
25
+ feature_set_name=name
26
+ )
27
+ except Exception as e:
28
+ print(
29
+ f"{Color.RED} Failed to trigger a batch feature set ingestion for feature set {name} {Color.END}"
30
+ )
31
+ raise FrogmlException(
32
+ f"Failed to trigger a batch feature set ingestion for feature set {name}"
33
+ ) from e
34
+
35
+ print(
36
+ f"{Color.GREEN}Successfully triggered a batch feature set ingestion for feature set: {Color.YELLOW}{name}"
37
+ )
38
+ if result.execution_id:
39
+ print(f"{Color.WHITE} Execution ID: {Color.YELLOW}{result.execution_id}")
File without changes
File without changes
File without changes
@@ -0,0 +1,42 @@
1
+ from typing import Tuple
2
+
3
+ from frogml.core.inner.build_config.build_config_v1 import BuildConfigV1
4
+ from frogml.core.inner.build_logic.interface.build_phase import BuildPhase
5
+ from frogml.core.inner.build_logic.phases.phases_pipeline import PhasesPipeline
6
+ from frogml.core.inner.build_logic.trigger_build_context import TriggerBuildContext
7
+
8
+ from .client_logs.messages import SUCCESS_MSG_REMOTE_WITH_DEPLOY, SUCCESS_MSG_REMOTE
9
+ from .phase.a_fetch_model_code import get_fetch_model_code_steps
10
+ from .phase.b_remote_register_frogml_build import get_remote_register_frogml_build_steps
11
+ from .phase.c_deploy import get_deploy_steps
12
+
13
+
14
+ def remote_build_steps(config: BuildConfigV1) -> PhasesPipeline:
15
+ steps_root = PhasesPipeline(config=config, context=TriggerBuildContext())
16
+ steps_root.add_phase(
17
+ steps=get_fetch_model_code_steps(),
18
+ build_phase=BuildPhase(phase_id="FETCHING_MODEL_CODE"),
19
+ )
20
+ steps_root.add_phase(
21
+ steps=get_remote_register_frogml_build_steps(),
22
+ build_phase=BuildPhase(phase_id="REGISTERING_FROGML_BUILD"),
23
+ )
24
+
25
+ if config.deploy:
26
+ steps_root.add_phase(
27
+ steps=get_deploy_steps(),
28
+ build_phase=BuildPhase(phase_id="DEPLOYING_PHASE", name="Deploying", description="Deploying"),
29
+ )
30
+
31
+ return steps_root
32
+
33
+
34
+ def create_pipeline(
35
+ config: BuildConfigV1,
36
+ ) -> Tuple[PhasesPipeline, str]:
37
+ success_message = (
38
+ SUCCESS_MSG_REMOTE_WITH_DEPLOY if config.deploy else SUCCESS_MSG_REMOTE
39
+ )
40
+ pipeline = remote_build_steps(config)
41
+
42
+ return pipeline, success_message
@@ -0,0 +1,123 @@
1
+ from contextlib import contextmanager
2
+ from logging import Logger
3
+ from pathlib import Path
4
+
5
+ from frogml.core.inner.build_logic.interface.build_phase import BuildPhase
6
+ from frogml.core.inner.build_logic.interface.phase_run_handler import PhaseRunHandler
7
+ from frogml.core.inner.build_logic.phases.phases_pipeline import PhasesPipeline
8
+ from yaspin import yaspin
9
+
10
+ from frogml_cli.tools.colors import Color
11
+ from .cli_trigger_build_logger import CliTriggerBuildLogger
12
+ from .messages import (
13
+ FAILED_CONTACT_JFROG_SUPPORT,
14
+ )
15
+ from .utils import zip_logs
16
+
17
+
18
+ class CLIPhaseRunHandler(PhaseRunHandler):
19
+ BUILD_IN_PROGRESS_FORMAT = "Build phase in progress: {}"
20
+ BUILD_FINISHED_FORMAT = "Phase successfully finished: {} after {} seconds"
21
+ KEYBOARD_INTERRUPT_FORMAT = "\n{color}Stopping Qwak build (ctrl-c)"
22
+ BUILD_FAILURE_FORMAT = "Build phase failed: {} after {} seconds"
23
+ PIPELINE_ERROR = "\n{color}{ex}"
24
+ SPINNER_FINISH = "✅"
25
+ SPINNER_FAIL = "💥"
26
+ SPINNER_OK = "‼️"
27
+
28
+ def __init__(self, python_logger: Logger, log_path: Path, verbose: int, json_logs: bool):
29
+ self.sp = None
30
+ self.build_logger = None
31
+ self.log_path = str(log_path)
32
+ self.python_logger = python_logger
33
+ self.json_logs = json_logs
34
+ self.verbose = verbose
35
+
36
+ @contextmanager
37
+ def handle_current_phase(self, phase: PhasesPipeline):
38
+ build_logger = CliTriggerBuildLogger(
39
+ self.python_logger,
40
+ prefix="" if self.json_logs else phase.build_phase.description,
41
+ build_phase=phase.build_phase,
42
+ )
43
+ show = (self.verbose == 0 and not self.json_logs)
44
+ text = phase.build_phase.description
45
+ if show:
46
+ with yaspin(text=text, color="blue", timer=True).bold as sp:
47
+ self.sp = sp
48
+ build_logger.set_spinner(sp)
49
+ self.build_logger = build_logger
50
+ yield
51
+ else:
52
+ self.build_logger = build_logger
53
+ yield
54
+
55
+ def handle_phase_in_progress(self, build_phase: BuildPhase):
56
+ logger = self.build_logger or self.python_logger
57
+ logger.debug(
58
+ self.BUILD_IN_PROGRESS_FORMAT.format(build_phase.name)
59
+ )
60
+
61
+ def handle_phase_finished_successfully(
62
+ self, build_phase: BuildPhase, duration_in_seconds: int
63
+ ):
64
+ if self.sp:
65
+ self.sp.ok(self.SPINNER_FINISH)
66
+
67
+ logger = self.build_logger or self.python_logger
68
+ logger.debug(
69
+ self.BUILD_FINISHED_FORMAT.format(build_phase.name, duration_in_seconds))
70
+
71
+ def _report_failure(self, build_phase: BuildPhase, duration_in_seconds: int):
72
+ logger = self.build_logger or self.python_logger
73
+ logger.debug(
74
+ self.BUILD_FAILURE_FORMAT.format(build_phase.name, duration_in_seconds))
75
+
76
+ def handle_contact_support_error(
77
+ self, build_id: str, build_phase: BuildPhase, ex: BaseException, duration_in_seconds: int
78
+ ):
79
+ print(f"\n{ex}\n{FAILED_CONTACT_JFROG_SUPPORT.format(build_id=build_id, log_file=Path(self.log_path).parent / build_id)}")
80
+ zip_logs(log_path=self.log_path, build_id=build_id)
81
+ self._report_failure(build_phase, duration_in_seconds)
82
+ exit(1)
83
+
84
+ def handle_remote_build_error(
85
+ self, build_id: str, build_phase: BuildPhase, ex: BaseException, duration_in_seconds: int
86
+ ):
87
+ if self.sp:
88
+ self.sp.fail(self.SPINNER_FAIL)
89
+ print(self.PIPELINE_ERROR.format(color=Color.RED, ex=ex))
90
+ else:
91
+ print(f"\n{ex}")
92
+ self._report_failure(build_phase, duration_in_seconds)
93
+ exit(1)
94
+
95
+ def handle_keyboard_interrupt(
96
+ self, build_id: str, build_phase: BuildPhase, duration_in_seconds: int
97
+ ):
98
+ print(self.KEYBOARD_INTERRUPT_FORMAT.format(color=Color.RED))
99
+ zip_logs(log_path=self.log_path, build_id=build_id)
100
+ self._report_failure(build_phase, duration_in_seconds)
101
+ exit(1)
102
+
103
+ def handle_pipeline_exception(
104
+ self, build_id: str, build_phase: BuildPhase, ex: BaseException, duration_in_seconds: int
105
+ ):
106
+ if self.sp:
107
+ self.sp.fail("💥")
108
+ print(f"\n{Color.RED}{ex}")
109
+ zip_logs(
110
+ log_path=self.log_path,
111
+ build_id=build_id,
112
+ )
113
+ self._report_failure(build_phase, duration_in_seconds)
114
+ exit(1)
115
+
116
+ def handle_pipeline_quiet_exception(
117
+ self, build_id: str, build_phase: BuildPhase, ex: BaseException, duration_in_seconds: int
118
+ ):
119
+ if self.sp:
120
+ self.sp.ok(self.SPINNER_OK)
121
+ print(self.PIPELINE_ERROR.format(color=Color.RED, ex=ex))
122
+ self._report_failure(build_phase, duration_in_seconds)
123
+ exit(1)
@@ -0,0 +1,19 @@
1
+ from logging import Logger
2
+
3
+ from frogml.core.inner.build_logic.build_loggers.trigger_build_logger import TriggerBuildLogger
4
+ from frogml.core.inner.build_logic.interface.build_phase import BuildPhase
5
+ from yaspin.core import Yaspin
6
+
7
+
8
+ class CliTriggerBuildLogger(TriggerBuildLogger):
9
+ def __init__(self, logger: Logger, prefix: str, build_phase: BuildPhase, verbose: int = 0,
10
+ json_logs: bool = False) -> None:
11
+ super().__init__(logger, prefix, build_phase, verbose, json_logs)
12
+ self.spinner = None
13
+
14
+ def set_spinner(self, spinner: Yaspin):
15
+ self.spinner = spinner
16
+
17
+ def spinner_text(self, line: str) -> None:
18
+ if self.spinner:
19
+ self.spinner.text = f"{self.prefix}{line}"
@@ -0,0 +1,88 @@
1
+ import contextlib
2
+ import logging
3
+ import os
4
+ import platform
5
+ import shutil
6
+ import sys
7
+ import uuid
8
+ from pathlib import Path
9
+
10
+ from frogml.core.inner.build_config.build_config_v1 import BuildConfigV1
11
+ from frogml.core.inner.build_logic.constants.host_resource import HOST_FROGML_HIDDEN_FOLDER
12
+
13
+ from frogml_cli import __version__ as qwak_sdk_version
14
+ from frogml_cli.inner.tools.logger import setup_frogml_logger
15
+ from frogml_cli.inner.tools.logger.logger import (
16
+ BUILD_LOCAL_FILE_HANDLER_NAME,
17
+ BUILD_LOCAL_LOGGER_NAME,
18
+ CONSOLE_HANDLER_NAME,
19
+ REMOTE_CONSOLE_HANDLER_NAME,
20
+ REMOTE_LOGGER_NAME,
21
+ VERBOSITY_LEVEL_MAPPING,
22
+ get_frogml_logger,
23
+ non_frogml_logger_enabled,
24
+ set_file_handler_log_file,
25
+ set_handler_verbosity,
26
+ )
27
+
28
+ BUILDS_LOGS = HOST_FROGML_HIDDEN_FOLDER / "logs" / "build"
29
+ BUILD_LOG_NAME = "build.log"
30
+ MAX_LOGS_NUMBER = 15
31
+ DEBUG_LEVEL = 2
32
+
33
+
34
+ @contextlib.contextmanager
35
+ def get_build_logger(config: BuildConfigV1, json_logs: bool):
36
+ log_path = BUILDS_LOGS / config.build_properties.model_id / str(uuid.uuid4())[:4]
37
+ log_path.mkdir(parents=True, exist_ok=True)
38
+ try:
39
+ (log_path / "build_config.yml").write_text(config.to_yaml())
40
+ log_system_information(log_path)
41
+
42
+ log_file = log_path / BUILD_LOG_NAME
43
+ setup_frogml_logger()
44
+ yield setup_logger(
45
+ log_file=log_file, verbosity_level=config.verbose, json_logs=json_logs
46
+ ), log_path
47
+ finally:
48
+ # Cleanup - Save only x last zips
49
+ logs_zip_sorted_by_data = sorted(
50
+ BUILDS_LOGS.rglob("**/*"), key=os.path.getmtime
51
+ )[:-MAX_LOGS_NUMBER]
52
+ path: Path
53
+ for path in logs_zip_sorted_by_data:
54
+ if path.is_file():
55
+ os.remove(path)
56
+ elif path.is_dir():
57
+ shutil.rmtree(path, ignore_errors=True)
58
+
59
+
60
+ def setup_logger(
61
+ log_file: Path, verbosity_level: int, json_logs: bool
62
+ ) -> logging.Logger:
63
+ # Init logger
64
+ fallback_logger_name = (
65
+ BUILD_LOCAL_LOGGER_NAME if not json_logs else REMOTE_LOGGER_NAME
66
+ )
67
+ logger = get_frogml_logger(fallback_logger_name=fallback_logger_name)
68
+
69
+ if not non_frogml_logger_enabled():
70
+ if logger.name == BUILD_LOCAL_LOGGER_NAME:
71
+ set_file_handler_log_file(logger, BUILD_LOCAL_FILE_HANDLER_NAME, log_file)
72
+ set_handler_verbosity(
73
+ logger, CONSOLE_HANDLER_NAME, VERBOSITY_LEVEL_MAPPING[verbosity_level]
74
+ )
75
+ elif logger.name == REMOTE_LOGGER_NAME and json_logs:
76
+ set_handler_verbosity(
77
+ logger,
78
+ REMOTE_CONSOLE_HANDLER_NAME,
79
+ VERBOSITY_LEVEL_MAPPING[DEBUG_LEVEL],
80
+ )
81
+
82
+ return logger
83
+
84
+
85
+ def log_system_information(destination: Path):
86
+ (destination / "python_version").write_text(sys.version)
87
+ (destination / "qwak_sdk_version").write_text(qwak_sdk_version)
88
+ (destination / "os_detail").write_text(platform.platform())
@@ -0,0 +1,36 @@
1
+ BUILD_LOGS_URL = (
2
+ "{base_url}/models/{model_id}/build/{build_id}"
3
+ )
4
+
5
+ SUCCESS_MSG_REMOTE = """
6
+ Build ID \033[4m{build_id}\033[0m triggered remotely
7
+
8
+ ########### Follow build logs in the CLI
9
+ frogml models builds logs -b {build_id} --follow
10
+
11
+ ########### Follow build logs in the platform
12
+ {base_url}/models/{model_id}/build/{build_id}
13
+ """
14
+
15
+ SUCCESS_MSG_REMOTE_WITH_DEPLOY = """
16
+ Build ID \033[4m{build_id}\033[0m finished successfully and deployed
17
+
18
+ ########### View the model using platform
19
+ {base_url}/models/{model_id}
20
+ """
21
+
22
+ FAILED_CONTACT_JFROG_SUPPORT = """
23
+ Build ID \033[4m{build_id}\033[0m failed!!
24
+ You can share the logs from \033[4m{log_file}.zip\033[0m with the support team.
25
+ """
26
+
27
+ FAILED_REMOTE_BUILD_SUGGESTION = """
28
+ Your build failed. Check the failure reason in the platform:
29
+ {base_url}/models/{model_id}/build/{build_id}
30
+ """
31
+
32
+ FAILED_DEPLOY_BUILD_SUGGESTION = """
33
+ Deploying the build failed. Check the failure reason in the platform:
34
+ {base_url}/models/{model_id}?tabId=1
35
+ Try and redeploy this build either from the platform or the CLI
36
+ """
@@ -0,0 +1,14 @@
1
+ from contextlib import contextmanager
2
+ from typing import Generator, Optional
3
+
4
+ from yaspin import yaspin
5
+ from yaspin.core import Yaspin
6
+
7
+
8
+ @contextmanager
9
+ def spinner(text: Optional[str], show: bool) -> Generator[Yaspin, None, None]:
10
+ if show:
11
+ with yaspin(text=text, color="blue", timer=True).bold as sp:
12
+ yield sp
13
+ else:
14
+ yield
@@ -0,0 +1,54 @@
1
+ import logging
2
+ from logging import Logger
3
+
4
+ from frogml.core.inner.build_logic.interface.build_logger_interface import BuildLogger
5
+ from frogml.core.inner.build_logic.interface.build_phase import BuildPhase
6
+ from yaspin.core import Yaspin
7
+
8
+
9
+ PREFIX_FORMAT = "{prefix} - "
10
+ EXCEPTION_FORMAT = """Message: {line}
11
+ Exception: {e}
12
+ """
13
+
14
+
15
+ class TriggerBuildLogger(BuildLogger):
16
+ def __init__(
17
+ self, logger: Logger, prefix: str, build_phase: BuildPhase, verbose: int = 0, json_logs: bool = False,
18
+ ) -> None:
19
+ self.logger = logging.LoggerAdapter(
20
+ logger,
21
+ {
22
+ "phase": build_phase.description,
23
+ "phase_id": build_phase.phase_id,
24
+ },
25
+ )
26
+ self.prefix = PREFIX_FORMAT.format(prefix=prefix) if prefix else ""
27
+ self.spinner = None
28
+ self.verbose = verbose
29
+ self.json_logs = json_logs
30
+
31
+ def set_spinner(self, spinner: Yaspin):
32
+ self.spinner = spinner
33
+
34
+ def exception(self, line: str, e: BaseException) -> None:
35
+ self.logger.error(
36
+ EXCEPTION_FORMAT.format(line=line, e=e),
37
+ exc_info=False,
38
+ )
39
+
40
+ def error(self, line: str) -> None:
41
+ self.logger.error(f"{self.prefix}{line}")
42
+
43
+ def warning(self, line: str) -> None:
44
+ self.logger.warning(f"{self.prefix}{line}")
45
+
46
+ def info(self, line: str) -> None:
47
+ self.logger.info(f"{self.prefix}{line}")
48
+
49
+ def debug(self, line: str) -> None:
50
+ self.logger.debug(f"{self.prefix}{line}")
51
+
52
+ def spinner_text(self, line: str) -> None:
53
+ if self.spinner:
54
+ self.spinner.text = f"{self.prefix}{line}"
@@ -0,0 +1,12 @@
1
+ import shutil
2
+ from pathlib import Path
3
+
4
+
5
+ def zip_logs(log_path: str, build_id: str):
6
+ if build_id:
7
+ shutil.make_archive(
8
+ base_name=str(Path(log_path).parent / build_id),
9
+ format="zip",
10
+ root_dir=log_path,
11
+ )
12
+ shutil.rmtree(log_path, ignore_errors=True)
@@ -0,0 +1,20 @@
1
+ from typing import List
2
+
3
+ from frogml.core.inner.build_logic.interface.step_inteface import Step
4
+ from frogml.core.inner.build_logic.phases.phase_010_fetch_model.fetch_model_step import FetchModelStep
5
+ from frogml.core.inner.build_logic.phases.phase_010_fetch_model.post_fetch_validation_step import PostFetchValidationStep
6
+ from frogml.core.inner.build_logic.phases.phase_010_fetch_model.pre_fetch_validation_step import PreFetchValidationStep
7
+
8
+ from frogml_cli.commands.models.build._logic.phase.a_fetch_model_code.get_sdk_version_step import SdkVersionStep
9
+ from frogml_cli.commands.models.build._logic.util.step_decorator import add_decorator_to_steps
10
+
11
+
12
+ def get_fetch_model_code_steps() -> List[Step]:
13
+ phase_steps = [
14
+ SdkVersionStep(),
15
+ PreFetchValidationStep(),
16
+ FetchModelStep(),
17
+ PostFetchValidationStep(),
18
+ ]
19
+
20
+ return add_decorator_to_steps(phase_steps)
@@ -0,0 +1,15 @@
1
+ from frogml.core.inner.build_logic.interface.step_inteface import Step
2
+
3
+ from frogml_cli import __version__ as frogml_cli_version
4
+ from frogml_cli import __name__ as frogml_cli_name
5
+
6
+
7
+ class SdkVersionStep(Step):
8
+ def description(self) -> str:
9
+ return "Getting SDK Version"
10
+
11
+ def execute(self) -> None:
12
+ self.build_logger.debug(
13
+ "Getting sdk version"
14
+ )
15
+ self.context.frogml_cli_version = f"{frogml_cli_name}/{frogml_cli_version}"
@@ -0,0 +1,16 @@
1
+ from frogml.core.inner.build_logic.phases.phase_020_remote_register_frogml_build.cleanup_step import CleanupStep
2
+ from frogml.core.inner.build_logic.phases.phase_020_remote_register_frogml_build.start_remote_build_step import \
3
+ StartRemoteBuildStep
4
+ from frogml.core.inner.build_logic.phases.phase_020_remote_register_frogml_build.upload_step import UploadStep
5
+
6
+ from ...util.step_decorator import add_decorator_to_steps
7
+
8
+
9
+ def get_remote_register_frogml_build_steps():
10
+ phase_steps = [
11
+ UploadStep(),
12
+ StartRemoteBuildStep(),
13
+ CleanupStep(),
14
+ ]
15
+
16
+ return add_decorator_to_steps(phase_steps)
@@ -0,0 +1,6 @@
1
+ from .build_polling_status import BuildPollingStatusStep
2
+ from .deploy_build import DeployBuildStep
3
+
4
+
5
+ def get_deploy_steps():
6
+ return [BuildPollingStatusStep(), DeployBuildStep()]
@@ -0,0 +1,55 @@
1
+ from __future__ import annotations
2
+
3
+ import time
4
+
5
+ from frogml._proto.qwak.build.v1.build_api_pb2 import GetBuildResponse
6
+ from frogml._proto.qwak.build.v1.build_pb2 import BuildStatus
7
+
8
+ from frogml_cli.commands.models.build._logic.client_logs.messages import (
9
+ FAILED_REMOTE_BUILD_SUGGESTION,
10
+ )
11
+ from frogml.core.inner.build_logic.interface.step_inteface import Step
12
+ from frogml.core.exceptions import FrogmlRemoteBuildFailedException
13
+
14
+
15
+ class BuildPollingStatusStep(Step):
16
+ FINITE_BUILD_STATUSES = {
17
+ BuildStatus.REMOTE_BUILD_CANCELLED,
18
+ BuildStatus.REMOTE_BUILD_TIMED_OUT,
19
+ BuildStatus.FAILED,
20
+ BuildStatus.SUCCESSFUL,
21
+ }
22
+ SLEEP_BETWEEN_STATUS_CHECK = 10
23
+ REMOTE_BUILD_FAILURE_EXCEPTION_FORMAT = "Your build failed with status {status}"
24
+
25
+ def description(self) -> str:
26
+ return "Polling on Build Status"
27
+
28
+ def execute(self) -> None:
29
+ self.build_logger.info("Waiting for build to finish")
30
+ status = self.wait_for_finite_build_status()
31
+ if status != BuildStatus.SUCCESSFUL:
32
+ raise FrogmlRemoteBuildFailedException(
33
+ message=self.REMOTE_BUILD_FAILURE_EXCEPTION_FORMAT.format(
34
+ status=BuildStatus.Name(status)
35
+ ),
36
+ suggestion=FAILED_REMOTE_BUILD_SUGGESTION.format(
37
+ base_url=self.context.platform_url,
38
+ build_id=self.context.build_id,
39
+ model_id=self.context.model_id,
40
+ project_uuid=self.context.project_uuid,
41
+ ),
42
+ )
43
+ self.build_logger.info("Your build finished successfully")
44
+
45
+ def wait_for_finite_build_status(self) -> BuildStatus:
46
+ self.build_logger.spinner_text(line="Waiting for build to finish")
47
+ while True:
48
+ result: GetBuildResponse = (
49
+ self.context.client_builds_orchestrator.get_build(self.context.build_id)
50
+ )
51
+ status: BuildStatus = result.build.build_status
52
+ if status in self.FINITE_BUILD_STATUSES:
53
+ return status
54
+ self.build_logger.debug(f"Build status is currently {BuildStatus.Name(status)}")
55
+ time.sleep(self.SLEEP_BETWEEN_STATUS_CHECK)
@@ -0,0 +1,61 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import List
4
+
5
+ from frogml._proto.qwak.instance_template.instance_template_pb2 import (
6
+ InstanceTemplateSpec,
7
+ InstanceType,
8
+ )
9
+
10
+ from frogml_cli.commands.models.build._logic.client_logs.messages import (
11
+ FAILED_DEPLOY_BUILD_SUGGESTION,
12
+ )
13
+ from frogml.core.inner.build_logic.interface.step_inteface import Step
14
+ from frogml_cli.commands.models.deployments.deploy.realtime.ui import deploy_realtime
15
+ from frogml_cli.exceptions.frogml_deploy_new_build_failed import (
16
+ FrogmlDeployNewBuildFailedException,
17
+ )
18
+
19
+
20
+ class DeployBuildStep(Step):
21
+ DEPLOY_FAILURE_EXCEPTION_MESSAGE = "Deploying the build failed due to {e}"
22
+
23
+ def description(self) -> str:
24
+ return "Deploying Build"
25
+
26
+ def execute(self) -> None:
27
+ self.build_logger.info(f"Deploying build {self.context.build_id}")
28
+ try:
29
+ if self.config.deployment_instance:
30
+ template_id = self.config.deployment_instance
31
+ else:
32
+ template_id = self.get_smallest_deployment_template_id()
33
+ deploy_config = {
34
+ "build_id": self.context.build_id,
35
+ "model_id": self.context.model_id,
36
+ "instance": template_id,
37
+ }
38
+ deploy_realtime(from_file=None, out_conf=False, sync=False, **deploy_config)
39
+ self.build_logger.info(f"Finished deploying build {self.context.build_id}")
40
+ except Exception as e:
41
+ raise FrogmlDeployNewBuildFailedException(
42
+ message=self.DEPLOY_FAILURE_EXCEPTION_MESSAGE.format(e=e),
43
+ suggestion=FAILED_DEPLOY_BUILD_SUGGESTION.format(
44
+ base_url=self.context.platform_url,
45
+ build_id=self.context.build_id,
46
+ model_id=self.context.model_id,
47
+ project_uuid=self.context.project_uuid,
48
+ ),
49
+ )
50
+
51
+ def get_smallest_deployment_template_id(self):
52
+ instances: List[
53
+ InstanceTemplateSpec
54
+ ] = self.context.client_instance_template.list_instance_templates()
55
+ return list(
56
+ filter(
57
+ lambda template: template.order == 1
58
+ and template.instance_type == InstanceType.INSTANCE_TYPE_CPU,
59
+ instances,
60
+ )
61
+ )[0].id
@@ -0,0 +1,45 @@
1
+ from frogml.core.exceptions import FrogmlException
2
+
3
+
4
+ def protobuf_factory(
5
+ protobuf_class, exclude_fields=None, include_only=None, mapping=None
6
+ ):
7
+ def get_final_field_names(cls):
8
+ fields = dict(cls.__dataclass_fields__)
9
+ all_field_names = set(fields.keys())
10
+ excluded_fields = set(exclude_fields) if exclude_fields else set()
11
+ included_fields = set(include_only) if include_only else all_field_names
12
+ unrecognized_fields = included_fields.difference(all_field_names)
13
+ if unrecognized_fields:
14
+ raise FrogmlException(
15
+ f"Unknown fields were included: {list(unrecognized_fields)}"
16
+ )
17
+ return included_fields.difference(excluded_fields)
18
+
19
+ def protofy_decorator(cls):
20
+ if not hasattr(cls, "__dataclass_fields__"):
21
+ raise FrogmlException("Protofy must receive a dataclass")
22
+
23
+ fields_mapping = mapping if mapping else {}
24
+ final_field_names = get_final_field_names(cls)
25
+
26
+ def to_proto(self) -> protobuf_class:
27
+ final_fields = {}
28
+ for field_name in final_field_names:
29
+ field_val = self.__getattribute__(field_name)
30
+ field_name = (
31
+ fields_mapping[field_name]
32
+ if field_name in fields_mapping
33
+ else field_name
34
+ )
35
+ final_fields[field_name] = (
36
+ field_val.to_proto()
37
+ if hasattr(field_val, "to_proto")
38
+ else field_val
39
+ )
40
+ return protobuf_class(**final_fields)
41
+
42
+ setattr(cls, "to_proto", to_proto)
43
+ return cls
44
+
45
+ return protofy_decorator