qwak-sdk 0.1.0__py3-none-any.whl → 0.2.21rc0__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.

Potentially problematic release.


This version of qwak-sdk might be problematic. Click here for more details.

Files changed (305) hide show
  1. qwak_sdk/__init__.py +9 -0
  2. qwak_sdk/cli.py +51 -0
  3. qwak_sdk/commands/admin/__init__.py +0 -0
  4. qwak_sdk/commands/admin/admin_commands_group.py +17 -0
  5. qwak_sdk/commands/admin/apikeys/__init__.py +0 -0
  6. qwak_sdk/commands/admin/apikeys/api_keys_commands_group.py +17 -0
  7. qwak_sdk/commands/admin/apikeys/generate/__init__.py +0 -0
  8. qwak_sdk/commands/admin/apikeys/generate/_logic.py +21 -0
  9. qwak_sdk/commands/admin/apikeys/generate/ui.py +45 -0
  10. qwak_sdk/commands/admin/apikeys/revoke/__init__.py +0 -0
  11. qwak_sdk/commands/admin/apikeys/revoke/_logic.py +22 -0
  12. qwak_sdk/commands/admin/apikeys/revoke/ui.py +31 -0
  13. qwak_sdk/commands/audience/__init__.py +0 -0
  14. qwak_sdk/commands/audience/_logic/__init__.py +0 -0
  15. qwak_sdk/commands/audience/_logic/config/__init__.py +0 -0
  16. qwak_sdk/commands/audience/_logic/config/config_base.py +16 -0
  17. qwak_sdk/commands/audience/_logic/config/parser.py +28 -0
  18. qwak_sdk/commands/audience/_logic/config/v1/__init__.py +0 -0
  19. qwak_sdk/commands/audience/_logic/config/v1/audience_config.py +26 -0
  20. qwak_sdk/commands/audience/_logic/config/v1/conditions_config.py +60 -0
  21. qwak_sdk/commands/audience/_logic/config/v1/config_v1.py +24 -0
  22. qwak_sdk/commands/audience/_logic/config/v1/route_config.py +14 -0
  23. qwak_sdk/commands/audience/_logic/config/v1/spec.py +11 -0
  24. qwak_sdk/commands/auto_scalling/__init__.py +0 -0
  25. qwak_sdk/commands/auto_scalling/_logic/__init__.py +0 -0
  26. qwak_sdk/commands/auto_scalling/_logic/config/__init__.py +3 -0
  27. qwak_sdk/commands/auto_scalling/_logic/config/config.py +100 -0
  28. qwak_sdk/commands/auto_scalling/_logic/config/parser.py +21 -0
  29. qwak_sdk/commands/auto_scalling/attach/__init__.py +0 -0
  30. qwak_sdk/commands/auto_scalling/attach/_logic.py +43 -0
  31. qwak_sdk/commands/auto_scalling/attach/ui.py +21 -0
  32. qwak_sdk/commands/auto_scalling/autoscaling_commands_group.py +15 -0
  33. qwak_sdk/commands/automations/__init__.py +0 -0
  34. qwak_sdk/commands/automations/automations_commands_group.py +30 -0
  35. qwak_sdk/commands/automations/delete/__init__.py +0 -0
  36. qwak_sdk/commands/automations/delete/_logic.py +6 -0
  37. qwak_sdk/commands/automations/delete/ui.py +23 -0
  38. qwak_sdk/commands/automations/executions/__init__.py +0 -0
  39. qwak_sdk/commands/automations/executions/executions_commands_group.py +14 -0
  40. qwak_sdk/commands/automations/executions/list/__init__.py +0 -0
  41. qwak_sdk/commands/automations/executions/list/_logic.py +8 -0
  42. qwak_sdk/commands/automations/executions/list/ui.py +25 -0
  43. qwak_sdk/commands/automations/list/__init__.py +0 -0
  44. qwak_sdk/commands/automations/list/_logic.py +8 -0
  45. qwak_sdk/commands/automations/list/ui.py +21 -0
  46. qwak_sdk/commands/automations/register/__init__.py +0 -0
  47. qwak_sdk/commands/automations/register/_logic.py +43 -0
  48. qwak_sdk/commands/automations/register/ui.py +44 -0
  49. qwak_sdk/commands/feature_store/__init__.py +0 -0
  50. qwak_sdk/commands/feature_store/delete/__init__.py +0 -0
  51. qwak_sdk/commands/feature_store/delete/_logic.py +52 -0
  52. qwak_sdk/commands/feature_store/delete/ui.py +40 -0
  53. qwak_sdk/commands/feature_store/feature_store_command_group.py +25 -0
  54. qwak_sdk/commands/feature_store/list/__init__.py +0 -0
  55. qwak_sdk/commands/feature_store/list/ui.py +140 -0
  56. qwak_sdk/commands/feature_store/pause/__init__.py +0 -0
  57. qwak_sdk/commands/feature_store/pause/ui.py +18 -0
  58. qwak_sdk/commands/feature_store/register/__init__.py +0 -0
  59. qwak_sdk/commands/feature_store/register/_logic.py +289 -0
  60. qwak_sdk/commands/feature_store/register/ui.py +105 -0
  61. qwak_sdk/commands/feature_store/resume/__init__.py +0 -0
  62. qwak_sdk/commands/feature_store/resume/ui.py +18 -0
  63. qwak_sdk/commands/feature_store/trigger/__init__.py +0 -0
  64. qwak_sdk/commands/feature_store/trigger/ui.py +32 -0
  65. qwak_sdk/commands/models/__init__.py +0 -0
  66. qwak_sdk/commands/models/_logic/__init__.py +0 -0
  67. qwak_sdk/commands/models/_logic/variations.py +55 -0
  68. qwak_sdk/commands/models/build/__init__.py +0 -0
  69. qwak_sdk/commands/models/build/_logic/__init__.py +0 -0
  70. qwak_sdk/commands/models/build/_logic/build_steps.py +68 -0
  71. qwak_sdk/commands/models/build/_logic/client_logs/__init__.py +0 -0
  72. qwak_sdk/commands/models/build/_logic/client_logs/build_run_handlers.py +189 -0
  73. qwak_sdk/commands/models/build/_logic/client_logs/cli_ui.py +125 -0
  74. qwak_sdk/commands/models/build/_logic/client_logs/logger.py +88 -0
  75. qwak_sdk/commands/models/build/_logic/client_logs/messages.py +40 -0
  76. qwak_sdk/commands/models/build/_logic/client_logs/notifier_impl.py +49 -0
  77. qwak_sdk/commands/models/build/_logic/client_logs/spinner.py +14 -0
  78. qwak_sdk/commands/models/build/_logic/client_logs/time_source.py +37 -0
  79. qwak_sdk/commands/models/build/_logic/client_logs/utils.py +12 -0
  80. qwak_sdk/commands/models/build/_logic/config/config_v1.py +253 -0
  81. qwak_sdk/commands/models/build/_logic/constant/host_resource.py +4 -0
  82. qwak_sdk/commands/models/build/_logic/constant/step_description.py +29 -0
  83. qwak_sdk/commands/models/build/_logic/constant/temp_dir.py +2 -0
  84. qwak_sdk/commands/models/build/_logic/constant/upload_tag.py +5 -0
  85. qwak_sdk/commands/models/build/_logic/context.py +62 -0
  86. qwak_sdk/commands/models/build/_logic/interface/__init__.py +0 -0
  87. qwak_sdk/commands/models/build/_logic/interface/notifier_interface.py +29 -0
  88. qwak_sdk/commands/models/build/_logic/interface/step_inteface.py +29 -0
  89. qwak_sdk/commands/models/build/_logic/phase/__init__.py +0 -0
  90. qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/__init__.py +14 -0
  91. qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/fetch_model_step/__init__.py +0 -0
  92. qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/fetch_model_step/fetch_model_step.py +42 -0
  93. qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/fetch_model_step/fetch_strategy_manager/__init__.py +0 -0
  94. qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/fetch_model_step/fetch_strategy_manager/common.py +33 -0
  95. qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/fetch_model_step/fetch_strategy_manager/fetch_strategy_manager.py +60 -0
  96. qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/fetch_model_step/fetch_strategy_manager/strategy/__init__.py +0 -0
  97. qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/fetch_model_step/fetch_strategy_manager/strategy/folder/__init__.py +0 -0
  98. qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/fetch_model_step/fetch_strategy_manager/strategy/folder/folder_strategy.py +73 -0
  99. qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/fetch_model_step/fetch_strategy_manager/strategy/git/__init__.py +0 -0
  100. qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/fetch_model_step/fetch_strategy_manager/strategy/git/git_strategy.py +149 -0
  101. qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/fetch_model_step/fetch_strategy_manager/strategy/strategy.py +69 -0
  102. qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/fetch_model_step/fetch_strategy_manager/strategy/zip/__init__.py +0 -0
  103. qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/fetch_model_step/fetch_strategy_manager/strategy/zip/zip_strategy.py +64 -0
  104. qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/post_fetch_validation_step.py +117 -0
  105. qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/pre_fetch_validation_step.py +135 -0
  106. qwak_sdk/commands/models/build/_logic/phase/b_remote_register_qwak_build/__init__.py +11 -0
  107. qwak_sdk/commands/models/build/_logic/phase/b_remote_register_qwak_build/cleanup_step.py +20 -0
  108. qwak_sdk/commands/models/build/_logic/phase/b_remote_register_qwak_build/start_remote_build_step.py +42 -0
  109. qwak_sdk/commands/models/build/_logic/phase/b_remote_register_qwak_build/upload_step.py +349 -0
  110. qwak_sdk/commands/models/build/_logic/phase/c_deploy/__init__.py +6 -0
  111. qwak_sdk/commands/models/build/_logic/phase/c_deploy/build_polling_status.py +54 -0
  112. qwak_sdk/commands/models/build/_logic/phase/c_deploy/deploy_build.py +44 -0
  113. qwak_sdk/commands/models/build/_logic/util/__init__.py +0 -0
  114. qwak_sdk/commands/models/build/_logic/util/protobuf_factory.py +45 -0
  115. qwak_sdk/commands/models/build/_logic/util/step_decorator.py +37 -0
  116. qwak_sdk/commands/models/build/_logic/util/text.py +9 -0
  117. qwak_sdk/commands/models/build/ui.py +241 -0
  118. qwak_sdk/commands/models/builds/__init__.py +0 -0
  119. qwak_sdk/commands/models/builds/builds_commands_group.py +16 -0
  120. qwak_sdk/commands/models/builds/cancel/__init__.py +0 -0
  121. qwak_sdk/commands/models/builds/cancel/_logic.py +5 -0
  122. qwak_sdk/commands/models/builds/cancel/ui.py +15 -0
  123. qwak_sdk/commands/models/builds/logs/__init__.py +0 -0
  124. qwak_sdk/commands/models/builds/logs/ui.py +35 -0
  125. qwak_sdk/commands/models/builds/status/__init__.py +0 -0
  126. qwak_sdk/commands/models/builds/status/_logic.py +6 -0
  127. qwak_sdk/commands/models/builds/status/ui.py +30 -0
  128. qwak_sdk/commands/models/create/__init__.py +0 -0
  129. qwak_sdk/commands/models/create/_logic.py +35 -0
  130. qwak_sdk/commands/models/create/ui.py +27 -0
  131. qwak_sdk/commands/models/delete/__init__.py +0 -0
  132. qwak_sdk/commands/models/delete/_logic.py +5 -0
  133. qwak_sdk/commands/models/delete/ui.py +16 -0
  134. qwak_sdk/commands/models/deployments/__init__.py +0 -0
  135. qwak_sdk/commands/models/deployments/deploy/__init__.py +0 -0
  136. qwak_sdk/commands/models/deployments/deploy/_logic/__init__.py +0 -0
  137. qwak_sdk/commands/models/deployments/deploy/_logic/advance_deployment_options_handler.py +31 -0
  138. qwak_sdk/commands/models/deployments/deploy/_logic/base_deploy_executor.py +64 -0
  139. qwak_sdk/commands/models/deployments/deploy/_logic/deploy_config.py +241 -0
  140. qwak_sdk/commands/models/deployments/deploy/_logic/deployment.py +405 -0
  141. qwak_sdk/commands/models/deployments/deploy/_logic/deployment_message_helpers.py +98 -0
  142. qwak_sdk/commands/models/deployments/deploy/_logic/deployment_response_handler.py +154 -0
  143. qwak_sdk/commands/models/deployments/deploy/_logic/deployment_size_mapper.py +21 -0
  144. qwak_sdk/commands/models/deployments/deploy/_logic/get_latest_successful_build.py +31 -0
  145. qwak_sdk/commands/models/deployments/deploy/_logic/variations.py +79 -0
  146. qwak_sdk/commands/models/deployments/deploy/batch/__init__.py +0 -0
  147. qwak_sdk/commands/models/deployments/deploy/batch/_logic/__init__.py +0 -0
  148. qwak_sdk/commands/models/deployments/deploy/batch/_logic/advanced_deployment_mapper.py +14 -0
  149. qwak_sdk/commands/models/deployments/deploy/batch/_logic/deploy_executor.py +24 -0
  150. qwak_sdk/commands/models/deployments/deploy/batch/ui.py +104 -0
  151. qwak_sdk/commands/models/deployments/deploy/deploy_commands_group.py +19 -0
  152. qwak_sdk/commands/models/deployments/deploy/realtime/__init__.py +0 -0
  153. qwak_sdk/commands/models/deployments/deploy/realtime/_logic/__init__.py +0 -0
  154. qwak_sdk/commands/models/deployments/deploy/realtime/_logic/advanced_deployment_mapper.py +20 -0
  155. qwak_sdk/commands/models/deployments/deploy/realtime/_logic/deploy_executor.py +24 -0
  156. qwak_sdk/commands/models/deployments/deploy/realtime/_logic/serving_strategy_mapper.py +105 -0
  157. qwak_sdk/commands/models/deployments/deploy/realtime/ui.py +179 -0
  158. qwak_sdk/commands/models/deployments/deploy/streaming/__init__.py +0 -0
  159. qwak_sdk/commands/models/deployments/deploy/streaming/_logic/__init__.py +0 -0
  160. qwak_sdk/commands/models/deployments/deploy/streaming/_logic/deploy_executor.py +24 -0
  161. qwak_sdk/commands/models/deployments/deploy/streaming/_logic/serving_strategy_mapper.py +38 -0
  162. qwak_sdk/commands/models/deployments/deploy/streaming/ui.py +196 -0
  163. qwak_sdk/commands/models/deployments/undeploy/__init__.py +0 -0
  164. qwak_sdk/commands/models/deployments/undeploy/_logic/__init__.py +0 -0
  165. qwak_sdk/commands/models/deployments/undeploy/_logic/request_undeploy.py +176 -0
  166. qwak_sdk/commands/models/deployments/undeploy/_logic/variations.py +74 -0
  167. qwak_sdk/commands/models/deployments/undeploy/ui.py +78 -0
  168. qwak_sdk/commands/models/executions/__init__.py +0 -0
  169. qwak_sdk/commands/models/executions/cancel/__init__.py +0 -0
  170. qwak_sdk/commands/models/executions/cancel/_logic.py +9 -0
  171. qwak_sdk/commands/models/executions/cancel/ui.py +27 -0
  172. qwak_sdk/commands/models/executions/execution_commands_group.py +24 -0
  173. qwak_sdk/commands/models/executions/report/__init__.py +0 -0
  174. qwak_sdk/commands/models/executions/report/_logic.py +14 -0
  175. qwak_sdk/commands/models/executions/report/ui.py +43 -0
  176. qwak_sdk/commands/models/executions/start/__init__.py +0 -0
  177. qwak_sdk/commands/models/executions/start/_logic.py +16 -0
  178. qwak_sdk/commands/models/executions/start/ui.py +176 -0
  179. qwak_sdk/commands/models/executions/status/__init__.py +0 -0
  180. qwak_sdk/commands/models/executions/status/_logic.py +13 -0
  181. qwak_sdk/commands/models/executions/status/ui.py +27 -0
  182. qwak_sdk/commands/models/init/__init__.py +0 -0
  183. qwak_sdk/commands/models/init/_logic/__init__.py +0 -0
  184. qwak_sdk/commands/models/init/_logic/initialize_model_structure.py +40 -0
  185. qwak_sdk/commands/models/init/_logic/template/__init__.py +0 -0
  186. qwak_sdk/commands/models/init/_logic/template/churn/__init__.py +0 -0
  187. qwak_sdk/commands/models/init/_logic/template/churn/cookiecutter.json +3 -0
  188. qwak_sdk/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/__init__.py +0 -0
  189. qwak_sdk/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/main/__init__.py +5 -0
  190. qwak_sdk/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/main/conda.yml +10 -0
  191. qwak_sdk/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/main/data.csv +1001 -0
  192. qwak_sdk/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/main/model.py +95 -0
  193. qwak_sdk/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/tests/__init__.py +0 -0
  194. qwak_sdk/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/tests/it/__init__.py +0 -0
  195. qwak_sdk/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/tests/it/test_churn.py +32 -0
  196. qwak_sdk/commands/models/init/_logic/template/credit_risk/__init__.py +0 -0
  197. qwak_sdk/commands/models/init/_logic/template/credit_risk/cookiecutter.json +3 -0
  198. qwak_sdk/commands/models/init/_logic/template/credit_risk/{{cookiecutter.model_directory}}/__init__.py +0 -0
  199. qwak_sdk/commands/models/init/_logic/template/credit_risk/{{cookiecutter.model_directory}}/main/__init__.py +5 -0
  200. qwak_sdk/commands/models/init/_logic/template/credit_risk/{{cookiecutter.model_directory}}/main/conda.yml +10 -0
  201. qwak_sdk/commands/models/init/_logic/template/credit_risk/{{cookiecutter.model_directory}}/main/data.csv +1001 -0
  202. qwak_sdk/commands/models/init/_logic/template/credit_risk/{{cookiecutter.model_directory}}/main/model.py +108 -0
  203. qwak_sdk/commands/models/init/_logic/template/general/__init__.py +0 -0
  204. qwak_sdk/commands/models/init/_logic/template/general/cookiecutter.json +6 -0
  205. qwak_sdk/commands/models/init/_logic/template/general/{{cookiecutter.model_directory}}/__init__.py +0 -0
  206. qwak_sdk/commands/models/init/_logic/template/general/{{cookiecutter.model_directory}}/{{cookiecutter.main_directory}}/__init__.py +5 -0
  207. qwak_sdk/commands/models/init/_logic/template/general/{{cookiecutter.model_directory}}/{{cookiecutter.main_directory}}/conda.yml +8 -0
  208. qwak_sdk/commands/models/init/_logic/template/general/{{cookiecutter.model_directory}}/{{cookiecutter.main_directory}}/model.py +66 -0
  209. qwak_sdk/commands/models/init/_logic/template/general/{{cookiecutter.model_directory}}/{{cookiecutter.test_directory}}/__init__.py +0 -0
  210. qwak_sdk/commands/models/init/_logic/template/general/{{cookiecutter.model_directory}}/{{cookiecutter.test_directory}}/test_qwak_model.py +5 -0
  211. qwak_sdk/commands/models/init/_logic/template/titanic/__init__.py +0 -0
  212. qwak_sdk/commands/models/init/_logic/template/titanic/cookiecutter.json +3 -0
  213. qwak_sdk/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/__init__.py +0 -0
  214. qwak_sdk/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/main/__init__.py +5 -0
  215. qwak_sdk/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/main/conda.yml +10 -0
  216. qwak_sdk/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/main/model.py +98 -0
  217. qwak_sdk/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/tests/__init__.py +0 -0
  218. qwak_sdk/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/tests/it/__init__.py +0 -0
  219. qwak_sdk/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/tests/it/test_titanic.py +24 -0
  220. qwak_sdk/commands/models/init/_logic/template/titanic_poetry/__init__.py +0 -0
  221. qwak_sdk/commands/models/init/_logic/template/titanic_poetry/cookiecutter.json +3 -0
  222. qwak_sdk/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/__init__.py +0 -0
  223. qwak_sdk/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/main/__init__.py +5 -0
  224. qwak_sdk/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/main/model.py +98 -0
  225. qwak_sdk/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/main/pyproject.toml +18 -0
  226. qwak_sdk/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/tests/__init__.py +0 -0
  227. qwak_sdk/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/tests/it/__init__.py +0 -0
  228. qwak_sdk/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/tests/it/test_titanic.py +25 -0
  229. qwak_sdk/commands/models/init/ui.py +61 -0
  230. qwak_sdk/commands/models/list/__init__.py +0 -0
  231. qwak_sdk/commands/models/list/_logic.py +5 -0
  232. qwak_sdk/commands/models/list/ui.py +31 -0
  233. qwak_sdk/commands/models/models_command_group.py +36 -0
  234. qwak_sdk/commands/models/runtime/__init__.py +0 -0
  235. qwak_sdk/commands/models/runtime/feedback/__init__.py +0 -0
  236. qwak_sdk/commands/models/runtime/feedback/_logic.py +81 -0
  237. qwak_sdk/commands/models/runtime/feedback/ui.py +45 -0
  238. qwak_sdk/commands/models/runtime/logs/__init__.py +0 -0
  239. qwak_sdk/commands/models/runtime/logs/ui.py +63 -0
  240. qwak_sdk/commands/models/runtime/runtime_commands_group.py +21 -0
  241. qwak_sdk/commands/models/runtime/traffic_update/__init__.py +0 -0
  242. qwak_sdk/commands/models/runtime/traffic_update/_logic/__init__.py +0 -0
  243. qwak_sdk/commands/models/runtime/traffic_update/_logic/execute_runtime_update_traffic.py +54 -0
  244. qwak_sdk/commands/models/runtime/traffic_update/_logic/variations.py +84 -0
  245. qwak_sdk/commands/models/runtime/traffic_update/ui.py +37 -0
  246. qwak_sdk/commands/models/runtime/update/__init__.py +0 -0
  247. qwak_sdk/commands/models/runtime/update/_logic.py +9 -0
  248. qwak_sdk/commands/models/runtime/update/ui.py +15 -0
  249. qwak_sdk/commands/projects/__init__.py +0 -0
  250. qwak_sdk/commands/projects/create/__init__.py +0 -0
  251. qwak_sdk/commands/projects/create/_logic.py +6 -0
  252. qwak_sdk/commands/projects/create/ui.py +21 -0
  253. qwak_sdk/commands/projects/delete/__init__.py +0 -0
  254. qwak_sdk/commands/projects/delete/_logic.py +6 -0
  255. qwak_sdk/commands/projects/delete/ui.py +15 -0
  256. qwak_sdk/commands/projects/list/__init__.py +0 -0
  257. qwak_sdk/commands/projects/list/_logic.py +6 -0
  258. qwak_sdk/commands/projects/list/ui.py +36 -0
  259. qwak_sdk/commands/projects/projects_command_group.py +19 -0
  260. qwak_sdk/commands/secrets/__init__.py +0 -0
  261. qwak_sdk/commands/secrets/delete/__init__.py +0 -0
  262. qwak_sdk/commands/secrets/delete/_logic.py +5 -0
  263. qwak_sdk/commands/secrets/delete/ui.py +21 -0
  264. qwak_sdk/commands/secrets/get/__init__.py +0 -0
  265. qwak_sdk/commands/secrets/get/_logic.py +5 -0
  266. qwak_sdk/commands/secrets/get/ui.py +17 -0
  267. qwak_sdk/commands/secrets/secrets_commands_group.py +19 -0
  268. qwak_sdk/commands/secrets/set/__init__.py +0 -0
  269. qwak_sdk/commands/secrets/set/_logic.py +5 -0
  270. qwak_sdk/commands/secrets/set/ui.py +16 -0
  271. qwak_sdk/commands/ui_tools.py +18 -0
  272. qwak_sdk/common/__init__.py +0 -0
  273. qwak_sdk/common/run_config/__init__.py +22 -0
  274. qwak_sdk/common/run_config/base.py +101 -0
  275. qwak_sdk/common/run_config/utils.py +249 -0
  276. qwak_sdk/exceptions/__init__.py +11 -0
  277. qwak_sdk/exceptions/qwak_command_exception.py +2 -0
  278. qwak_sdk/exceptions/qwak_deploy_new_build_failed.py +5 -0
  279. qwak_sdk/exceptions/qwak_general_build_exception.py +13 -0
  280. qwak_sdk/exceptions/qwak_remote_build_failed.py +5 -0
  281. qwak_sdk/exceptions/qwak_resource_not_found.py +2 -0
  282. qwak_sdk/exceptions/qwak_suggestion_exception.py +27 -0
  283. qwak_sdk/inner/__init__.py +0 -0
  284. qwak_sdk/inner/file_registry.py +97 -0
  285. qwak_sdk/inner/tools/__init__.py +0 -0
  286. qwak_sdk/inner/tools/cli_tools.py +159 -0
  287. qwak_sdk/inner/tools/config_handler.py +18 -0
  288. qwak_sdk/inner/tools/logger/__init__.py +3 -0
  289. qwak_sdk/inner/tools/logger/logger.py +269 -0
  290. qwak_sdk/inner/tools/logger/logging.yml +79 -0
  291. qwak_sdk/inner/tools/tracking.py +47 -0
  292. qwak_sdk/main.py +9 -0
  293. qwak_sdk/tools/__init__.py +0 -0
  294. qwak_sdk/tools/colors.py +13 -0
  295. qwak_sdk/tools/files.py +9 -0
  296. qwak_sdk/tools/log_handling.py +146 -0
  297. qwak_sdk/tools/utils.py +46 -0
  298. qwak_sdk-0.2.21rc0.dist-info/METADATA +42 -0
  299. qwak_sdk-0.2.21rc0.dist-info/RECORD +302 -0
  300. {qwak_sdk-0.1.0.dist-info → qwak_sdk-0.2.21rc0.dist-info}/WHEEL +1 -2
  301. qwak_sdk-0.2.21rc0.dist-info/entry_points.txt +3 -0
  302. qwak_sdk-0.1.0.dist-info/METADATA +0 -19
  303. qwak_sdk-0.1.0.dist-info/RECORD +0 -5
  304. qwak_sdk-0.1.0.dist-info/top_level.txt +0 -1
  305. {qwak-sdk → qwak_sdk/commands}/__init__.py +0 -0
@@ -0,0 +1,253 @@
1
+ from dataclasses import dataclass, field
2
+ from os.path import expandvars
3
+ from typing import Dict, List, Optional, Tuple, Union
4
+
5
+ from _qwak_proto.qwak.builds.builds_pb2 import (
6
+ BuildConfiguration,
7
+ BuildEnvironment,
8
+ BuildModelUri,
9
+ BuildPropertiesProto,
10
+ CondaBuild,
11
+ DockerBuild,
12
+ LocalBuild,
13
+ PoetryBuild,
14
+ PythonBuild,
15
+ RemoteBuild,
16
+ RemoteBuildResources,
17
+ Step,
18
+ VirtualEnvironmentBuild,
19
+ )
20
+ from qwak.inner.tool.run_config import (
21
+ QwakConfigBase,
22
+ YamlConfigMixin,
23
+ validate_bool,
24
+ validate_float,
25
+ validate_int,
26
+ validate_list_of_strings,
27
+ validate_string,
28
+ )
29
+
30
+ from qwak_sdk.commands.models.build._logic.util.protobuf_factory import protobuf_factory
31
+ from qwak_sdk.common.run_config import ConfigCliMap
32
+
33
+ CONFIG_MAPPING: List[ConfigCliMap] = [
34
+ # ConfigV1
35
+ ConfigCliMap(
36
+ "validate_build_artifact", "step.validate_build_artifact", validate_bool, True
37
+ ),
38
+ ConfigCliMap(
39
+ "validate_build_artifact_timeout",
40
+ "step.validate_build_artifact_timeout",
41
+ validate_int,
42
+ True,
43
+ ),
44
+ ConfigCliMap("tests", "step.tests", validate_bool, True),
45
+ # BuildProperties
46
+ ConfigCliMap("model_id", "build_properties.model_id", validate_string, True),
47
+ ConfigCliMap("build_id", "build_properties.build_id", validate_string, False),
48
+ ConfigCliMap(
49
+ "gpu_compatible", "build_properties.gpu_compatible", validate_bool, False
50
+ ),
51
+ ConfigCliMap("branch", "build_properties.branch", validate_string),
52
+ ConfigCliMap("tags", "build_properties.tags", validate_list_of_strings),
53
+ # ModelUri
54
+ ConfigCliMap("uri", "build_properties.model_uri.uri", validate_string, False),
55
+ ConfigCliMap(
56
+ "git_branch", "build_properties.model_uri.git_branch", validate_string
57
+ ),
58
+ ConfigCliMap("main_dir", "build_properties.model_uri.main_dir", validate_string),
59
+ ConfigCliMap(
60
+ "git_credentials", "build_properties.model_uri.git_credentials", validate_string
61
+ ),
62
+ ConfigCliMap(
63
+ "git_credentials_secret",
64
+ "build_properties.model_uri.git_credentials_secret",
65
+ validate_string,
66
+ ),
67
+ ConfigCliMap(
68
+ "dependency_required_folders",
69
+ "build_properties.model_uri.dependency_required_folders",
70
+ validate_list_of_strings,
71
+ ),
72
+ # BuildEnv
73
+ # PythonEnv
74
+ ConfigCliMap(
75
+ "dependency_file_path",
76
+ "build_env.python_env.dependency_file_path",
77
+ validate_string,
78
+ ),
79
+ # DockerConf
80
+ ConfigCliMap("base_image", "build_env.docker.base_image", validate_string),
81
+ ConfigCliMap("param_list", "build_env.docker.params", validate_list_of_strings),
82
+ ConfigCliMap("env_vars", "build_env.docker.env_vars", validate_list_of_strings),
83
+ ConfigCliMap("cache", "build_env.docker.cache", validate_bool),
84
+ ConfigCliMap(
85
+ "iam_role_arn", "build_env.docker.assumed_iam_role_arn", validate_string
86
+ ),
87
+ # LocalConf
88
+ ConfigCliMap("push", "build_env.docker.push", validate_bool),
89
+ ConfigCliMap("aws_profile", "build_env.local.aws_profile", validate_string),
90
+ # RemoteConf
91
+ ConfigCliMap("remote", "build_env.remote.is_remote", validate_bool),
92
+ ConfigCliMap("cpus", "build_env.remote.resources.cpus", validate_float),
93
+ ConfigCliMap("memory", "build_env.remote.resources.memory", validate_string),
94
+ ConfigCliMap("gpu_type", "build_env.remote.resources.gpu_type", validate_string),
95
+ ConfigCliMap("gpu_amount", "build_env.remote.resources.gpu_amount", validate_int),
96
+ # Verbosity level
97
+ ConfigCliMap("verbose", "verbose", validate_int),
98
+ ConfigCliMap("deploy", "deploy", validate_bool),
99
+ ]
100
+
101
+
102
+ @protobuf_factory(BuildConfiguration, exclude_fields=["deploy"])
103
+ @dataclass
104
+ class ConfigV1(YamlConfigMixin, QwakConfigBase):
105
+ @property
106
+ def _config_mapping(self) -> List[ConfigCliMap]:
107
+ return CONFIG_MAPPING
108
+
109
+ @protobuf_factory(Step)
110
+ @dataclass
111
+ class Step:
112
+ validate_build_artifact: bool = field(default=True)
113
+ validate_build_artifact_timeout: int = field(default=120)
114
+ tests: bool = field(default=True)
115
+
116
+ @protobuf_factory(BuildPropertiesProto, exclude_fields=["gpu_compatible"])
117
+ @dataclass
118
+ class BuildProperties:
119
+ @protobuf_factory(
120
+ BuildModelUri,
121
+ exclude_fields=[
122
+ "git_credentials",
123
+ "git_credentials_secret",
124
+ "dependency_required_folders",
125
+ ],
126
+ )
127
+ @dataclass
128
+ class ModelUri:
129
+ uri: Optional[str] = field(default=None)
130
+ git_branch: Optional[str] = field(default="master")
131
+ main_dir: Optional[str] = field(default="main")
132
+ dependency_required_folders: List[str] = field(default_factory=list)
133
+ git_credentials: Optional[str] = field(default=None)
134
+ git_credentials_secret: Optional[str] = field(default=None)
135
+
136
+ build_id: Optional[str] = field(default=None)
137
+ gpu_compatible: bool = field(default=False)
138
+ branch: Optional[str] = field(default="main")
139
+ model_id: str = field(default="")
140
+ tags: List[str] = field(default_factory=list)
141
+ model_uri: ModelUri = field(default_factory=ModelUri)
142
+
143
+ @protobuf_factory(BuildEnvironment)
144
+ @dataclass
145
+ class BuildEnv:
146
+ @protobuf_factory(DockerBuild)
147
+ @dataclass
148
+ class DockerConf:
149
+ base_image: Optional[str] = field(
150
+ default="public.ecr.aws/w8k8y6b6/qwak-base:0.0.18-cpu"
151
+ )
152
+ env_vars: Optional[Union[List[str], Dict[str, str], Tuple]] = field(
153
+ default_factory=list
154
+ )
155
+ assumed_iam_role_arn: str = field(default=None)
156
+ params: Optional[List[str]] = field(default_factory=list)
157
+ no_cache: bool = field(default=False)
158
+ cache: bool = field(default=True)
159
+ push: bool = field(default=True)
160
+
161
+ @protobuf_factory(
162
+ PythonBuild, exclude_fields=["git_credentials_secret", "git_credentials"]
163
+ )
164
+ @dataclass
165
+ class PythonEnv:
166
+ @protobuf_factory(PoetryBuild)
167
+ @dataclass
168
+ class PoetryType:
169
+ python_version: Optional[str] = field(default=None)
170
+ lock_file: Optional[str] = field(default=None)
171
+
172
+ @protobuf_factory(CondaBuild)
173
+ @dataclass
174
+ class CondaType:
175
+ conda_file: Optional[str] = field(default=None)
176
+
177
+ @protobuf_factory(VirtualEnvironmentBuild)
178
+ @dataclass
179
+ class VirtualenvType:
180
+ python_version: Optional[str] = field(default=None)
181
+ requirements_txt: Optional[str] = field(default=None)
182
+
183
+ git_credentials: Optional[str] = field(default=None)
184
+ git_credentials_secret: Optional[str] = field(default=None)
185
+ poetry: PoetryType = field(default=None)
186
+ conda: CondaType = field(default=None)
187
+ virtualenv: VirtualenvType = field(default=None)
188
+ qwak_sdk_extra_index_url: str = field(default=None)
189
+ dependency_file_path: Optional[str] = field(default=None)
190
+
191
+ def __post_init__(self):
192
+ if not (self.poetry or self.conda or self.virtualenv):
193
+ self.conda = self.CondaType("conda.yml")
194
+
195
+ @protobuf_factory(LocalBuild)
196
+ @dataclass
197
+ class LocalConf:
198
+ no_push: bool = field(default=False) # Deprecated
199
+ aws_profile: str = field(default=None)
200
+
201
+ @protobuf_factory(RemoteBuild)
202
+ @dataclass
203
+ class RemoteConf:
204
+ @protobuf_factory(RemoteBuildResources)
205
+ @dataclass
206
+ class RemoteBuildResources:
207
+ cpus: Optional[float] = field(default=None)
208
+ memory: Optional[str] = field(default=None)
209
+ gpu_type: Optional[str] = field(default=None)
210
+ gpu_amount: Optional[int] = field(default=None)
211
+
212
+ is_remote: bool = field(default=True)
213
+ resources: RemoteBuildResources = field(
214
+ default_factory=RemoteBuildResources
215
+ )
216
+
217
+ docker: DockerConf = field(default_factory=DockerConf)
218
+ python_env: PythonEnv = field(default_factory=PythonEnv)
219
+ local: LocalConf = field(default_factory=LocalConf)
220
+ remote: RemoteConf = field(default_factory=RemoteConf)
221
+
222
+ build_properties: BuildProperties = field(default_factory=BuildProperties)
223
+ build_env: Optional[BuildEnv] = field(default_factory=BuildEnv)
224
+ pre_build: Optional[BuildEnv] = field(default=None)
225
+ post_build: Optional[BuildEnv] = field(default=None)
226
+ step: Step = field(default_factory=Step)
227
+ deploy: bool = field(default=False)
228
+ verbose: int = field(default=0)
229
+
230
+ def __post_init__(self):
231
+ if (
232
+ self.build_env.remote.resources.gpu_type
233
+ and self.build_env.docker.base_image
234
+ == ConfigV1.BuildEnv.DockerConf.base_image
235
+ or self.build_properties.gpu_compatible
236
+ ):
237
+ self.build_env.docker.base_image = (
238
+ "public.ecr.aws/w8k8y6b6/qwak-base:0.0.6-gpu"
239
+ )
240
+ if isinstance(self.build_env.docker.env_vars, (list, tuple)):
241
+ self.build_env.docker.env_vars = [
242
+ expandvars(var) for var in self.build_env.docker.env_vars
243
+ ]
244
+
245
+ def _post_merge_cli(self):
246
+ """Implementing post merge actions."""
247
+ self.build_properties.model_id = self.build_properties.model_id.lower()
248
+ self.build_properties.tags = list(self.build_properties.tags)
249
+ self.build_properties.model_uri.dependency_required_folders = list(
250
+ self.build_properties.model_uri.dependency_required_folders
251
+ )
252
+ self.build_env.docker.env_vars = list(self.build_env.docker.env_vars)
253
+ self.build_env.docker.params = list(self.build_env.docker.params)
@@ -0,0 +1,4 @@
1
+ from pathlib import Path
2
+
3
+ HOST_QWAK_HIDDEN_FOLDER = Path.home() / ".qwak"
4
+ HOST_TEMP_BUILD_DIR = HOST_QWAK_HIDDEN_FOLDER / "builds"
@@ -0,0 +1,29 @@
1
+ from enum import Enum
2
+
3
+ FETCHING_MODEL_CODE_PHASE_DESCRIPTION = "Fetching Model Code"
4
+ REGISTER_QWAK_BUILD_PHASE_DESCRIPTION = "Registering Qwak Build"
5
+ DEPLOY_PHASE_DESCRIPTION = "Deploying"
6
+
7
+
8
+ class BuildPhase(Enum):
9
+ FETCHING_MODEL_CODE = 1
10
+ REGISTERING_QWAK_BUILD = 2
11
+ DEPLOY_PHASE = 3
12
+
13
+
14
+ class PhaseDetails:
15
+ def __init__(self, build_phase: BuildPhase):
16
+ self.phase = build_phase
17
+
18
+ def get_id(self):
19
+ return str(self.phase.name)
20
+
21
+ def get_description(self):
22
+ if self.phase == BuildPhase.FETCHING_MODEL_CODE:
23
+ return FETCHING_MODEL_CODE_PHASE_DESCRIPTION
24
+ elif self.phase == BuildPhase.REGISTERING_QWAK_BUILD:
25
+ return REGISTER_QWAK_BUILD_PHASE_DESCRIPTION
26
+ elif self.phase == BuildPhase.DEPLOY_PHASE:
27
+ return DEPLOY_PHASE_DESCRIPTION
28
+ else:
29
+ raise ValueError("Invalid PhaseId")
@@ -0,0 +1,2 @@
1
+ TEMP_LOCAL_MODEL_DIR = "model_code"
2
+ TEMP_LOCAL_EDITABLE_SDK = "editable"
@@ -0,0 +1,5 @@
1
+ MODEL_CODE_TAG = "code.zip"
2
+ SKINNY_MODEL_CODE_TAG = "skinny_code.zip"
3
+ QWAK_SDK_VERSION_TAG = "qwak_sdk_version"
4
+ QWAK_SDK_WHEEL_TAG = "qwak_sdk_wheel"
5
+ BUILD_CONFIG_TAG = "qwak_build_config"
@@ -0,0 +1,62 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, field
4
+ from enum import Enum
5
+ from pathlib import Path
6
+ from typing import Optional
7
+
8
+ from qwak.clients.build_management import BuildsManagementClient
9
+ from qwak.clients.build_orchestrator import BuildOrchestratorClient
10
+ from qwak.clients.model_management import ModelsManagementClient
11
+ from qwak.inner.di_configuration import UserAccountConfiguration
12
+ from qwak.inner.di_configuration.account import UserAccount
13
+
14
+
15
+ class DependencyManagerType(Enum):
16
+ UNKNOWN = 0
17
+ PIP = 1
18
+ POETRY = 2
19
+ CONDA = 3
20
+
21
+
22
+ @dataclass
23
+ class Context:
24
+ # Clients
25
+ client_builds_orchestrator: BuildOrchestratorClient = field(
26
+ default_factory=BuildOrchestratorClient
27
+ )
28
+ client_build_management: BuildsManagementClient = field(
29
+ default_factory=BuildsManagementClient
30
+ )
31
+ client_models_management: ModelsManagementClient = field(
32
+ default_factory=ModelsManagementClient
33
+ )
34
+
35
+ # General
36
+ user_account: UserAccount = field(
37
+ default_factory=UserAccountConfiguration().get_user_config
38
+ )
39
+
40
+ # Pre fetch validation
41
+ build_id: str = field(default="")
42
+ model_id: str = field(default="")
43
+ project_uuid: str = field(default="")
44
+ host_temp_local_build_dir: Path = field(default=None)
45
+ model_uri: Path = field(default=None)
46
+ git_credentials: str = field(default="")
47
+
48
+ # Fetch model
49
+ git_commit_id: Optional[str] = field(default=None)
50
+
51
+ # Post fetch validation
52
+ dependency_manager_type: DependencyManagerType = field(
53
+ default=DependencyManagerType.UNKNOWN
54
+ )
55
+ model_relative_dependency_file: Path = field(default=None)
56
+ model_relative_dependency_lock_file: Path = field(default=None)
57
+
58
+ # Upload model
59
+ model_code_remote_url: Optional[str] = field(default=None)
60
+
61
+ # Image
62
+ base_image: Optional[str] = field(default=None)
@@ -0,0 +1,29 @@
1
+ from __future__ import annotations
2
+
3
+ from abc import ABC, abstractmethod
4
+
5
+
6
+ class Notifier(ABC):
7
+ @abstractmethod
8
+ def error(self, line: str) -> None:
9
+ pass
10
+
11
+ @abstractmethod
12
+ def exception(self, line: str, e: BaseException) -> None:
13
+ pass
14
+
15
+ @abstractmethod
16
+ def warning(self, line: str) -> None:
17
+ pass
18
+
19
+ @abstractmethod
20
+ def info(self, line: str) -> None:
21
+ pass
22
+
23
+ @abstractmethod
24
+ def debug(self, line: str) -> None:
25
+ pass
26
+
27
+ @abstractmethod
28
+ def spinner_text(self, line: str) -> None:
29
+ pass
@@ -0,0 +1,29 @@
1
+ from __future__ import annotations
2
+
3
+ from abc import ABC, abstractmethod
4
+ from typing import TYPE_CHECKING
5
+
6
+ from qwak_sdk.commands.models.build._logic.config.config_v1 import ConfigV1
7
+ from qwak_sdk.commands.models.build._logic.constant.step_description import BuildPhase
8
+ from qwak_sdk.commands.models.build._logic.context import Context
9
+
10
+ if TYPE_CHECKING:
11
+ from qwak_sdk.commands.models.build import Notifier
12
+
13
+
14
+ class Step(ABC):
15
+ context: Context
16
+ config: ConfigV1
17
+ notifier: Notifier
18
+ build_phase: BuildPhase
19
+
20
+ @abstractmethod
21
+ def description(self) -> str:
22
+ pass
23
+
24
+ @abstractmethod
25
+ def execute(self) -> None:
26
+ pass
27
+
28
+ def set_notifier(self, notifier: Notifier) -> None:
29
+ self.notifier = notifier
@@ -0,0 +1,14 @@
1
+ from typing import List
2
+
3
+ from ...interface.step_inteface import Step
4
+ from .fetch_model_step.fetch_model_step import FetchModelStep
5
+ from .post_fetch_validation_step import PostFetchValidationStep
6
+ from .pre_fetch_validation_step import PreFetchValidationStep
7
+
8
+
9
+ def get_fetch_model_code_steps() -> List[Step]:
10
+ return [
11
+ PreFetchValidationStep(),
12
+ FetchModelStep(),
13
+ PostFetchValidationStep(),
14
+ ]
@@ -0,0 +1,42 @@
1
+ from __future__ import annotations
2
+
3
+ from qwak_sdk.commands.models.build._logic.constant.temp_dir import TEMP_LOCAL_MODEL_DIR
4
+ from qwak_sdk.commands.models.build._logic.interface.step_inteface import Step
5
+ from qwak_sdk.commands.models.build._logic.phase.a_fetch_model_code.fetch_model_step.fetch_strategy_manager.fetch_strategy_manager import (
6
+ FetchStrategyManager,
7
+ )
8
+ from qwak_sdk.commands.models.build._logic.util.step_decorator import (
9
+ build_failure_handler,
10
+ )
11
+
12
+
13
+ class FetchModelStep(Step):
14
+ def description(self) -> str:
15
+ return "Fetch model code"
16
+
17
+ @build_failure_handler()
18
+ def execute(self) -> None:
19
+ fetch_strategy_manager = FetchStrategyManager(
20
+ uri=self.config.build_properties.model_uri.uri,
21
+ notifier=self.notifier,
22
+ )
23
+ self.notifier.debug("Fetching model code")
24
+ git_commit_id = fetch_strategy_manager.fetch(
25
+ dest=self.context.host_temp_local_build_dir / TEMP_LOCAL_MODEL_DIR,
26
+ git_branch=self.config.build_properties.model_uri.git_branch,
27
+ git_credentials=self.context.git_credentials,
28
+ model_id=self.config.build_properties.model_id,
29
+ build_id=self.context.build_id,
30
+ custom_dependencies_path=self.config.build_env.python_env.dependency_file_path,
31
+ main_dir=self.config.build_properties.model_uri.main_dir,
32
+ dependency_path=self.context.model_relative_dependency_file,
33
+ dependency_required_folders=self.config.build_properties.model_uri.dependency_required_folders,
34
+ )
35
+ if git_commit_id:
36
+ self.context.git_commit_id = git_commit_id
37
+ self.notifier.debug(f"Git commit ID identified - {git_commit_id}")
38
+
39
+ self.notifier.debug(
40
+ f"Model code stored in {self.context.host_temp_local_build_dir / TEMP_LOCAL_MODEL_DIR}"
41
+ )
42
+ self.notifier.info("Successfully fetched model code")
@@ -0,0 +1,33 @@
1
+ import re
2
+ from pathlib import Path
3
+ from typing import Union
4
+
5
+ _GIT_URI_REGEX = re.compile(r"^[^/]*:")
6
+ _FILE_URI_REGEX = re.compile(r"^file://.+")
7
+ _ZIP_URI_REGEX = re.compile(r".+\.zip")
8
+
9
+
10
+ def is_zip_uri(uri: Union[str, Path]) -> bool:
11
+ return uri and _ZIP_URI_REGEX.match(str(uri)) is not None
12
+
13
+
14
+ def is_local_dir(uri: Union[str, Path]) -> bool:
15
+ return uri and not _GIT_URI_REGEX.match(str(uri)) and Path(uri).is_dir()
16
+
17
+
18
+ def is_git_uri(uri: Union[str, Path]) -> bool:
19
+ return uri and _GIT_URI_REGEX.match(str(uri)) is not None
20
+
21
+
22
+ def get_git_commit_id(path: Union[str, Path], notifier) -> str:
23
+ try:
24
+ import git
25
+ from git import InvalidGitRepositoryError
26
+
27
+ repo = git.Repo(path=path, search_parent_directories=True)
28
+ return repo.head.object.hexsha
29
+ except InvalidGitRepositoryError:
30
+ return ""
31
+ except Exception as e:
32
+ notifier.warning(f"Failed to get git commit with error: {e}")
33
+ return ""
@@ -0,0 +1,60 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, List, Optional
4
+
5
+ from qwak_sdk.exceptions import QwakSuggestionException
6
+
7
+ from .common import is_git_uri, is_local_dir, is_zip_uri
8
+ from .strategy.folder.folder_strategy import FolderStrategy
9
+ from .strategy.git.git_strategy import GitStrategy
10
+ from .strategy.strategy import Strategy
11
+ from .strategy.zip.zip_strategy import ZipStrategy
12
+
13
+ URI_CHECK_STRATEGY_MAPPING = {
14
+ is_local_dir: FolderStrategy,
15
+ is_git_uri: GitStrategy,
16
+ is_zip_uri: ZipStrategy,
17
+ }
18
+
19
+ if TYPE_CHECKING:
20
+ from qwak_sdk.commands.models.build import Notifier
21
+
22
+
23
+ class FetchStrategyManager:
24
+ def __init__(self, uri: str, notifier: Notifier) -> None:
25
+ self._strategy: Optional[Strategy] = None
26
+ self._uri = uri
27
+ for check, clazz in URI_CHECK_STRATEGY_MAPPING.items():
28
+ if check(uri):
29
+ self._strategy = clazz(notifier)
30
+
31
+ if self._strategy is None:
32
+ raise QwakSuggestionException(
33
+ message=f"Model URI {uri} is no valid.",
34
+ suggestion=f"Please make sure that model path: {uri} is a zip file/git uri/local folder.",
35
+ )
36
+
37
+ def fetch(
38
+ self,
39
+ dest: str,
40
+ git_branch: str,
41
+ git_credentials: str,
42
+ model_id: str,
43
+ build_id: str,
44
+ custom_dependencies_path: str,
45
+ main_dir: str,
46
+ dependency_path: str,
47
+ dependency_required_folders: List[str],
48
+ ) -> str:
49
+ return self._strategy.fetch(
50
+ src=self._uri,
51
+ dest=dest,
52
+ git_branch=git_branch,
53
+ git_credentials=git_credentials,
54
+ model_id=model_id,
55
+ build_id=build_id,
56
+ custom_dependencies_path=custom_dependencies_path,
57
+ main_dir=main_dir,
58
+ dependency_path=dependency_path,
59
+ dependency_required_folders=dependency_required_folders,
60
+ )
@@ -0,0 +1,73 @@
1
+ import shutil
2
+ from pathlib import Path
3
+ from typing import List, Optional
4
+
5
+ from qwak_sdk.exceptions import QwakSuggestionException
6
+ from qwak_sdk.tools.files import copytree
7
+
8
+ from ...common import get_git_commit_id
9
+ from ..strategy import Strategy, get_ignore_pattern
10
+
11
+
12
+ class FolderStrategy(Strategy):
13
+ def fetch(
14
+ self,
15
+ src: str,
16
+ dest: str,
17
+ custom_dependencies_path: Optional[str],
18
+ main_dir: str,
19
+ dependency_path: str,
20
+ dependency_required_folders: List[str],
21
+ **kwargs,
22
+ ) -> Optional[str]:
23
+ try:
24
+ self.notifier.debug(f"Fetching Model code from local directory - {src}")
25
+
26
+ ignore_patterns, patterns_for_printing = get_ignore_pattern(
27
+ src, main_dir, self.notifier
28
+ )
29
+ self.notifier.debug(
30
+ f"Will ignore the following files: {patterns_for_printing}."
31
+ )
32
+
33
+ copytree(
34
+ src=Path(src) / main_dir,
35
+ dst=Path(dest) / main_dir,
36
+ ignore=ignore_patterns,
37
+ )
38
+ for folder in dependency_required_folders:
39
+ if (Path(src) / folder).exists():
40
+ copytree(
41
+ src=Path(src) / folder,
42
+ dst=Path(dest) / folder,
43
+ ignore=ignore_patterns,
44
+ )
45
+ else:
46
+ self.notifier.warning(
47
+ 'Folder "{}" does not exist. Skipping it.'.format(folder)
48
+ )
49
+ if (Path(src) / "tests").exists():
50
+ copytree(
51
+ src=Path(src) / "tests",
52
+ dst=Path(dest) / "tests",
53
+ ignore=ignore_patterns,
54
+ )
55
+ if dependency_path:
56
+ shutil.copy(
57
+ src=Path(src) / dependency_path, dst=Path(dest) / dependency_path
58
+ )
59
+
60
+ # Copy custom dependencies path
61
+ if custom_dependencies_path and Path(custom_dependencies_path).is_file():
62
+ shutil.copy(
63
+ src=custom_dependencies_path,
64
+ dst=Path(dest) / Path(custom_dependencies_path).name,
65
+ )
66
+ # Get git commit id if exists
67
+ return get_git_commit_id(src, self.notifier)
68
+ except Exception as e:
69
+ raise QwakSuggestionException(
70
+ message="Unable to copy model.",
71
+ src_exception=e,
72
+ suggestion=f"Please make sure that {src} has read permissions.",
73
+ )