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.
- qwak_sdk/__init__.py +9 -0
- qwak_sdk/cli.py +79 -0
- qwak_sdk/commands/__init__.py +0 -0
- qwak_sdk/commands/_logic/__init__.py +0 -0
- qwak_sdk/commands/_logic/tools.py +6 -0
- qwak_sdk/commands/admin/__init__.py +0 -0
- qwak_sdk/commands/admin/admin_commands_group.py +17 -0
- qwak_sdk/commands/admin/apikeys/__init__.py +0 -0
- qwak_sdk/commands/admin/apikeys/api_keys_commands_group.py +17 -0
- qwak_sdk/commands/admin/apikeys/generate/__init__.py +0 -0
- qwak_sdk/commands/admin/apikeys/generate/_logic.py +21 -0
- qwak_sdk/commands/admin/apikeys/generate/ui.py +45 -0
- qwak_sdk/commands/admin/apikeys/revoke/__init__.py +0 -0
- qwak_sdk/commands/admin/apikeys/revoke/_logic.py +22 -0
- qwak_sdk/commands/admin/apikeys/revoke/ui.py +31 -0
- qwak_sdk/commands/alerts/__init__.py +0 -0
- qwak_sdk/commands/alerts/alerts_commnad_group.py +18 -0
- qwak_sdk/commands/alerts/delete/__init__.py +0 -0
- qwak_sdk/commands/alerts/delete/_logic.py +5 -0
- qwak_sdk/commands/alerts/delete/ui.py +10 -0
- qwak_sdk/commands/alerts/list/__init__.py +0 -0
- qwak_sdk/commands/alerts/list/_logic.py +23 -0
- qwak_sdk/commands/alerts/list/ui.py +17 -0
- qwak_sdk/commands/alerts/register/__init__.py +0 -0
- qwak_sdk/commands/alerts/register/_logic.py +72 -0
- qwak_sdk/commands/alerts/register/ui.py +30 -0
- qwak_sdk/commands/audience/__init__.py +0 -0
- qwak_sdk/commands/audience/_logic/__init__.py +0 -0
- qwak_sdk/commands/audience/_logic/config/__init__.py +0 -0
- qwak_sdk/commands/audience/_logic/config/config_base.py +15 -0
- qwak_sdk/commands/audience/_logic/config/parser.py +30 -0
- qwak_sdk/commands/audience/_logic/config/v1/__init__.py +0 -0
- qwak_sdk/commands/audience/_logic/config/v1/audience_config.py +26 -0
- qwak_sdk/commands/audience/_logic/config/v1/conditions_config.py +59 -0
- qwak_sdk/commands/audience/_logic/config/v1/config_v1.py +23 -0
- qwak_sdk/commands/audience/_logic/config/v1/route_config.py +15 -0
- qwak_sdk/commands/audience/_logic/config/v1/spec.py +9 -0
- qwak_sdk/commands/audience/audience_api_dump.py +86 -0
- qwak_sdk/commands/audience/audience_commands_group.py +30 -0
- qwak_sdk/commands/audience/create/__init__.py +0 -0
- qwak_sdk/commands/audience/create/logic.py +41 -0
- qwak_sdk/commands/audience/create/ui.py +21 -0
- qwak_sdk/commands/audience/delete/__init__.py +0 -0
- qwak_sdk/commands/audience/delete/logic.py +13 -0
- qwak_sdk/commands/audience/delete/ui.py +17 -0
- qwak_sdk/commands/audience/get/__init__.py +0 -0
- qwak_sdk/commands/audience/get/logic.py +14 -0
- qwak_sdk/commands/audience/get/ui.py +25 -0
- qwak_sdk/commands/audience/list/__init__.py +0 -0
- qwak_sdk/commands/audience/list/logic.py +16 -0
- qwak_sdk/commands/audience/list/ui.py +26 -0
- qwak_sdk/commands/audience/update/__init__.py +0 -0
- qwak_sdk/commands/audience/update/logic.py +37 -0
- qwak_sdk/commands/audience/update/ui.py +26 -0
- qwak_sdk/commands/auto_scalling/__init__.py +0 -0
- qwak_sdk/commands/auto_scalling/_logic/__init__.py +0 -0
- qwak_sdk/commands/auto_scalling/_logic/config/__init__.py +3 -0
- qwak_sdk/commands/auto_scalling/_logic/config/config.py +152 -0
- qwak_sdk/commands/auto_scalling/_logic/config/parser.py +21 -0
- qwak_sdk/commands/auto_scalling/attach/__init__.py +0 -0
- qwak_sdk/commands/auto_scalling/attach/_logic.py +43 -0
- qwak_sdk/commands/auto_scalling/attach/ui.py +21 -0
- qwak_sdk/commands/auto_scalling/autoscaling_commands_group.py +15 -0
- qwak_sdk/commands/automations/__init__.py +0 -0
- qwak_sdk/commands/automations/automations_commands_group.py +30 -0
- qwak_sdk/commands/automations/delete/__init__.py +0 -0
- qwak_sdk/commands/automations/delete/_logic.py +6 -0
- qwak_sdk/commands/automations/delete/ui.py +23 -0
- qwak_sdk/commands/automations/executions/__init__.py +0 -0
- qwak_sdk/commands/automations/executions/executions_commands_group.py +14 -0
- qwak_sdk/commands/automations/executions/list/__init__.py +0 -0
- qwak_sdk/commands/automations/executions/list/_logic.py +8 -0
- qwak_sdk/commands/automations/executions/list/ui.py +25 -0
- qwak_sdk/commands/automations/list/__init__.py +0 -0
- qwak_sdk/commands/automations/list/_logic.py +36 -0
- qwak_sdk/commands/automations/list/ui.py +21 -0
- qwak_sdk/commands/automations/register/__init__.py +0 -0
- qwak_sdk/commands/automations/register/_logic.py +43 -0
- qwak_sdk/commands/automations/register/ui.py +44 -0
- qwak_sdk/commands/feature_store/__init__.py +0 -0
- qwak_sdk/commands/feature_store/backfill/__init__.py +0 -0
- qwak_sdk/commands/feature_store/backfill/_logic.py +140 -0
- qwak_sdk/commands/feature_store/backfill/streaming/__init__.py +0 -0
- qwak_sdk/commands/feature_store/backfill/streaming/_logic.py +50 -0
- qwak_sdk/commands/feature_store/backfill/streaming/ui.py +67 -0
- qwak_sdk/commands/feature_store/backfill/ui.py +146 -0
- qwak_sdk/commands/feature_store/delete/__init__.py +0 -0
- qwak_sdk/commands/feature_store/delete/_logic.py +104 -0
- qwak_sdk/commands/feature_store/delete/ui.py +40 -0
- qwak_sdk/commands/feature_store/execution/__init__.py +0 -0
- qwak_sdk/commands/feature_store/execution/ui.py +19 -0
- qwak_sdk/commands/feature_store/feature_store_command_group.py +29 -0
- qwak_sdk/commands/feature_store/list/__init__.py +0 -0
- qwak_sdk/commands/feature_store/list/ui.py +140 -0
- qwak_sdk/commands/feature_store/pause/__init__.py +0 -0
- qwak_sdk/commands/feature_store/pause/ui.py +18 -0
- qwak_sdk/commands/feature_store/register/__init__.py +0 -0
- qwak_sdk/commands/feature_store/register/_logic.py +367 -0
- qwak_sdk/commands/feature_store/register/ui.py +111 -0
- qwak_sdk/commands/feature_store/resume/__init__.py +0 -0
- qwak_sdk/commands/feature_store/resume/ui.py +18 -0
- qwak_sdk/commands/feature_store/trigger/__init__.py +0 -0
- qwak_sdk/commands/feature_store/trigger/ui.py +39 -0
- qwak_sdk/commands/models/__init__.py +0 -0
- qwak_sdk/commands/models/build/__init__.py +0 -0
- qwak_sdk/commands/models/build/_logic/__init__.py +0 -0
- qwak_sdk/commands/models/build/_logic/build_steps.py +42 -0
- qwak_sdk/commands/models/build/_logic/client_logs/__init__.py +0 -0
- qwak_sdk/commands/models/build/_logic/client_logs/cli_phase_run_handler.py +123 -0
- qwak_sdk/commands/models/build/_logic/client_logs/cli_trigger_build_logger.py +19 -0
- qwak_sdk/commands/models/build/_logic/client_logs/logger.py +88 -0
- qwak_sdk/commands/models/build/_logic/client_logs/messages.py +36 -0
- qwak_sdk/commands/models/build/_logic/client_logs/spinner.py +14 -0
- qwak_sdk/commands/models/build/_logic/client_logs/trigger_build_logger.py +54 -0
- qwak_sdk/commands/models/build/_logic/client_logs/utils.py +12 -0
- qwak_sdk/commands/models/build/_logic/phase/__init__.py +0 -0
- qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/__init__.py +20 -0
- qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/get_sdk_version_step.py +14 -0
- qwak_sdk/commands/models/build/_logic/phase/b_remote_register_qwak_build/__init__.py +16 -0
- qwak_sdk/commands/models/build/_logic/phase/c_deploy/__init__.py +6 -0
- qwak_sdk/commands/models/build/_logic/phase/c_deploy/build_polling_status.py +55 -0
- qwak_sdk/commands/models/build/_logic/phase/c_deploy/deploy_build.py +61 -0
- qwak_sdk/commands/models/build/_logic/util/__init__.py +0 -0
- qwak_sdk/commands/models/build/_logic/util/protobuf_factory.py +45 -0
- qwak_sdk/commands/models/build/_logic/util/step_decorator.py +60 -0
- qwak_sdk/commands/models/build/_logic/util/text.py +9 -0
- qwak_sdk/commands/models/build/_logic/wait_until_finished.py +27 -0
- qwak_sdk/commands/models/build/ui.py +337 -0
- qwak_sdk/commands/models/builds/__init__.py +0 -0
- qwak_sdk/commands/models/builds/builds_commands_group.py +16 -0
- qwak_sdk/commands/models/builds/cancel/__init__.py +0 -0
- qwak_sdk/commands/models/builds/cancel/_logic.py +5 -0
- qwak_sdk/commands/models/builds/cancel/ui.py +15 -0
- qwak_sdk/commands/models/builds/logs/__init__.py +0 -0
- qwak_sdk/commands/models/builds/logs/ui.py +35 -0
- qwak_sdk/commands/models/builds/status/__init__.py +0 -0
- qwak_sdk/commands/models/builds/status/_logic.py +6 -0
- qwak_sdk/commands/models/builds/status/ui.py +39 -0
- qwak_sdk/commands/models/create/__init__.py +0 -0
- qwak_sdk/commands/models/create/_logic.py +36 -0
- qwak_sdk/commands/models/create/ui.py +43 -0
- qwak_sdk/commands/models/delete/__init__.py +0 -0
- qwak_sdk/commands/models/delete/_logic.py +5 -0
- qwak_sdk/commands/models/delete/ui.py +25 -0
- qwak_sdk/commands/models/deployments/__init__.py +0 -0
- qwak_sdk/commands/models/deployments/deploy/__init__.py +0 -0
- qwak_sdk/commands/models/deployments/deploy/_logic/__init__.py +0 -0
- qwak_sdk/commands/models/deployments/deploy/_logic/advance_deployment_options_handler.py +31 -0
- qwak_sdk/commands/models/deployments/deploy/_logic/base_deploy_executor.py +68 -0
- qwak_sdk/commands/models/deployments/deploy/_logic/deploy_config.py +261 -0
- qwak_sdk/commands/models/deployments/deploy/_logic/deployment.py +405 -0
- qwak_sdk/commands/models/deployments/deploy/_logic/deployment_message_helpers.py +114 -0
- qwak_sdk/commands/models/deployments/deploy/_logic/deployment_response_handler.py +156 -0
- qwak_sdk/commands/models/deployments/deploy/_logic/deployment_size_mapper.py +96 -0
- qwak_sdk/commands/models/deployments/deploy/_logic/get_latest_successful_build.py +28 -0
- qwak_sdk/commands/models/deployments/deploy/_logic/local_deployment.py +193 -0
- qwak_sdk/commands/models/deployments/deploy/batch/__init__.py +0 -0
- qwak_sdk/commands/models/deployments/deploy/batch/_logic/__init__.py +0 -0
- qwak_sdk/commands/models/deployments/deploy/batch/_logic/advanced_deployment_mapper.py +15 -0
- qwak_sdk/commands/models/deployments/deploy/batch/_logic/deploy_executor.py +24 -0
- qwak_sdk/commands/models/deployments/deploy/batch/ui.py +126 -0
- qwak_sdk/commands/models/deployments/deploy/deploy_commands_group.py +19 -0
- qwak_sdk/commands/models/deployments/deploy/realtime/__init__.py +0 -0
- qwak_sdk/commands/models/deployments/deploy/realtime/_logic/__init__.py +0 -0
- qwak_sdk/commands/models/deployments/deploy/realtime/_logic/advanced_deployment_mapper.py +21 -0
- qwak_sdk/commands/models/deployments/deploy/realtime/_logic/deploy_executor.py +24 -0
- qwak_sdk/commands/models/deployments/deploy/realtime/_logic/serving_strategy_mapper.py +75 -0
- qwak_sdk/commands/models/deployments/deploy/realtime/ui.py +209 -0
- qwak_sdk/commands/models/deployments/deploy/streaming/__init__.py +0 -0
- qwak_sdk/commands/models/deployments/deploy/streaming/_logic/__init__.py +0 -0
- qwak_sdk/commands/models/deployments/deploy/streaming/_logic/deploy_executor.py +24 -0
- qwak_sdk/commands/models/deployments/deploy/streaming/_logic/serving_strategy_mapper.py +38 -0
- qwak_sdk/commands/models/deployments/deploy/streaming/ui.py +213 -0
- qwak_sdk/commands/models/deployments/undeploy/__init__.py +0 -0
- qwak_sdk/commands/models/deployments/undeploy/_logic/__init__.py +0 -0
- qwak_sdk/commands/models/deployments/undeploy/_logic/request_undeploy.py +249 -0
- qwak_sdk/commands/models/deployments/undeploy/ui.py +72 -0
- qwak_sdk/commands/models/describe/__init__.py +0 -0
- qwak_sdk/commands/models/describe/_logic.py +169 -0
- qwak_sdk/commands/models/describe/ui.py +35 -0
- qwak_sdk/commands/models/executions/__init__.py +0 -0
- qwak_sdk/commands/models/executions/cancel/__init__.py +0 -0
- qwak_sdk/commands/models/executions/cancel/_logic.py +9 -0
- qwak_sdk/commands/models/executions/cancel/ui.py +27 -0
- qwak_sdk/commands/models/executions/execution_commands_group.py +24 -0
- qwak_sdk/commands/models/executions/report/__init__.py +0 -0
- qwak_sdk/commands/models/executions/report/_logic.py +14 -0
- qwak_sdk/commands/models/executions/report/ui.py +43 -0
- qwak_sdk/commands/models/executions/start/__init__.py +0 -0
- qwak_sdk/commands/models/executions/start/_logic.py +81 -0
- qwak_sdk/commands/models/executions/start/ui.py +208 -0
- qwak_sdk/commands/models/executions/status/__init__.py +0 -0
- qwak_sdk/commands/models/executions/status/_logic.py +13 -0
- qwak_sdk/commands/models/executions/status/ui.py +27 -0
- qwak_sdk/commands/models/init/__init__.py +0 -0
- qwak_sdk/commands/models/init/_logic/__init__.py +0 -0
- qwak_sdk/commands/models/init/_logic/initialize_model_structure.py +40 -0
- qwak_sdk/commands/models/init/_logic/template/__init__.py +0 -0
- qwak_sdk/commands/models/init/_logic/template/churn/__init__.py +0 -0
- qwak_sdk/commands/models/init/_logic/template/churn/cookiecutter.json +3 -0
- qwak_sdk/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/__init__.py +0 -0
- qwak_sdk/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/main/__init__.py +5 -0
- qwak_sdk/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/main/conda.yml +10 -0
- qwak_sdk/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/main/data.csv +1001 -0
- qwak_sdk/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/main/model.py +95 -0
- qwak_sdk/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/tests/__init__.py +0 -0
- qwak_sdk/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/tests/it/__init__.py +0 -0
- qwak_sdk/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/tests/it/test_churn.py +32 -0
- qwak_sdk/commands/models/init/_logic/template/credit_risk/__init__.py +0 -0
- qwak_sdk/commands/models/init/_logic/template/credit_risk/cookiecutter.json +3 -0
- qwak_sdk/commands/models/init/_logic/template/credit_risk/{{cookiecutter.model_directory}}/__init__.py +0 -0
- qwak_sdk/commands/models/init/_logic/template/credit_risk/{{cookiecutter.model_directory}}/main/__init__.py +5 -0
- qwak_sdk/commands/models/init/_logic/template/credit_risk/{{cookiecutter.model_directory}}/main/conda.yml +11 -0
- qwak_sdk/commands/models/init/_logic/template/credit_risk/{{cookiecutter.model_directory}}/main/data.csv +1001 -0
- qwak_sdk/commands/models/init/_logic/template/credit_risk/{{cookiecutter.model_directory}}/main/model.py +108 -0
- qwak_sdk/commands/models/init/_logic/template/general/__init__.py +0 -0
- qwak_sdk/commands/models/init/_logic/template/general/cookiecutter.json +6 -0
- qwak_sdk/commands/models/init/_logic/template/general/{{cookiecutter.model_directory}}/__init__.py +0 -0
- qwak_sdk/commands/models/init/_logic/template/general/{{cookiecutter.model_directory}}/{{cookiecutter.main_directory}}/__init__.py +5 -0
- qwak_sdk/commands/models/init/_logic/template/general/{{cookiecutter.model_directory}}/{{cookiecutter.main_directory}}/conda.yml +8 -0
- qwak_sdk/commands/models/init/_logic/template/general/{{cookiecutter.model_directory}}/{{cookiecutter.main_directory}}/model.py +66 -0
- qwak_sdk/commands/models/init/_logic/template/general/{{cookiecutter.model_directory}}/{{cookiecutter.test_directory}}/__init__.py +0 -0
- qwak_sdk/commands/models/init/_logic/template/general/{{cookiecutter.model_directory}}/{{cookiecutter.test_directory}}/test_qwak_model.py +5 -0
- qwak_sdk/commands/models/init/_logic/template/titanic/__init__.py +0 -0
- qwak_sdk/commands/models/init/_logic/template/titanic/cookiecutter.json +3 -0
- qwak_sdk/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/__init__.py +0 -0
- qwak_sdk/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/main/__init__.py +5 -0
- qwak_sdk/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/main/conda.yml +11 -0
- qwak_sdk/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/main/model.py +98 -0
- qwak_sdk/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/tests/__init__.py +0 -0
- qwak_sdk/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/tests/it/__init__.py +0 -0
- qwak_sdk/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/tests/it/test_titanic.py +24 -0
- qwak_sdk/commands/models/init/_logic/template/titanic_poetry/__init__.py +0 -0
- qwak_sdk/commands/models/init/_logic/template/titanic_poetry/cookiecutter.json +3 -0
- qwak_sdk/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/__init__.py +0 -0
- qwak_sdk/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/main/__init__.py +5 -0
- qwak_sdk/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/main/model.py +98 -0
- qwak_sdk/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/main/pyproject.toml +20 -0
- qwak_sdk/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/tests/__init__.py +0 -0
- qwak_sdk/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/tests/it/__init__.py +0 -0
- qwak_sdk/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/tests/it/test_titanic.py +25 -0
- qwak_sdk/commands/models/init/ui.py +61 -0
- qwak_sdk/commands/models/list/__init__.py +0 -0
- qwak_sdk/commands/models/list/_logic.py +5 -0
- qwak_sdk/commands/models/list/ui.py +40 -0
- qwak_sdk/commands/models/list_models/__init__.py +0 -0
- qwak_sdk/commands/models/list_models/_logic.py +5 -0
- qwak_sdk/commands/models/list_models/ui.py +60 -0
- qwak_sdk/commands/models/metadata/__init__.py +0 -0
- qwak_sdk/commands/models/metadata/_logic.py +5 -0
- qwak_sdk/commands/models/metadata/ui.py +60 -0
- qwak_sdk/commands/models/models_command_group.py +44 -0
- qwak_sdk/commands/models/runtime/__init__.py +0 -0
- qwak_sdk/commands/models/runtime/logs/__init__.py +0 -0
- qwak_sdk/commands/models/runtime/logs/ui.py +63 -0
- qwak_sdk/commands/models/runtime/runtime_commands_group.py +17 -0
- qwak_sdk/commands/models/runtime/update/__init__.py +0 -0
- qwak_sdk/commands/models/runtime/update/_logic.py +9 -0
- qwak_sdk/commands/models/runtime/update/ui.py +15 -0
- qwak_sdk/commands/projects/__init__.py +0 -0
- qwak_sdk/commands/projects/create/__init__.py +0 -0
- qwak_sdk/commands/projects/create/_logic.py +9 -0
- qwak_sdk/commands/projects/create/ui.py +68 -0
- qwak_sdk/commands/projects/delete/__init__.py +0 -0
- qwak_sdk/commands/projects/delete/_logic.py +6 -0
- qwak_sdk/commands/projects/delete/ui.py +24 -0
- qwak_sdk/commands/projects/list/__init__.py +0 -0
- qwak_sdk/commands/projects/list/_logic.py +6 -0
- qwak_sdk/commands/projects/list/ui.py +45 -0
- qwak_sdk/commands/projects/projects_command_group.py +19 -0
- qwak_sdk/commands/secrets/__init__.py +0 -0
- qwak_sdk/commands/secrets/delete/__init__.py +0 -0
- qwak_sdk/commands/secrets/delete/_logic.py +5 -0
- qwak_sdk/commands/secrets/delete/ui.py +21 -0
- qwak_sdk/commands/secrets/get/__init__.py +0 -0
- qwak_sdk/commands/secrets/get/_logic.py +5 -0
- qwak_sdk/commands/secrets/get/ui.py +17 -0
- qwak_sdk/commands/secrets/secrets_commands_group.py +19 -0
- qwak_sdk/commands/secrets/set/__init__.py +0 -0
- qwak_sdk/commands/secrets/set/_logic.py +5 -0
- qwak_sdk/commands/secrets/set/ui.py +16 -0
- qwak_sdk/commands/ui_tools.py +18 -0
- qwak_sdk/commands/workspaces/__init__.py +0 -0
- qwak_sdk/commands/workspaces/_logic/__init__.py +0 -0
- qwak_sdk/commands/workspaces/_logic/tools.py +44 -0
- qwak_sdk/commands/workspaces/_logic/workspace_validations.py +41 -0
- qwak_sdk/commands/workspaces/config/__init__.py +0 -0
- qwak_sdk/commands/workspaces/config/workspace_config.py +35 -0
- qwak_sdk/commands/workspaces/create/__init__.py +0 -0
- qwak_sdk/commands/workspaces/create/_logic.py +54 -0
- qwak_sdk/commands/workspaces/create/ui.py +48 -0
- qwak_sdk/commands/workspaces/delete/__init__.py +0 -0
- qwak_sdk/commands/workspaces/delete/_logic.py +30 -0
- qwak_sdk/commands/workspaces/delete/ui.py +23 -0
- qwak_sdk/commands/workspaces/start/__init__.py +0 -0
- qwak_sdk/commands/workspaces/start/_logic.py +30 -0
- qwak_sdk/commands/workspaces/start/ui.py +23 -0
- qwak_sdk/commands/workspaces/stop/__init__.py +0 -0
- qwak_sdk/commands/workspaces/stop/_logic.py +30 -0
- qwak_sdk/commands/workspaces/stop/ui.py +23 -0
- qwak_sdk/commands/workspaces/update/__init__.py +0 -0
- qwak_sdk/commands/workspaces/update/_logic.py +82 -0
- qwak_sdk/commands/workspaces/update/ui.py +57 -0
- qwak_sdk/commands/workspaces/workspaces_commands_group.py +23 -0
- qwak_sdk/exceptions/__init__.py +11 -0
- qwak_sdk/exceptions/qwak_command_exception.py +2 -0
- qwak_sdk/exceptions/qwak_deploy_new_build_failed.py +5 -0
- qwak_sdk/exceptions/qwak_resource_not_found.py +2 -0
- qwak_sdk/inner/__init__.py +0 -0
- qwak_sdk/inner/file_registry.py +98 -0
- qwak_sdk/inner/tools/__init__.py +0 -0
- qwak_sdk/inner/tools/cli_tools.py +220 -0
- qwak_sdk/inner/tools/config_handler.py +27 -0
- qwak_sdk/inner/tools/dataclasses_utils.py +21 -0
- qwak_sdk/inner/tools/logger/__init__.py +3 -0
- qwak_sdk/inner/tools/logger/logger.py +269 -0
- qwak_sdk/inner/tools/logger/logging.yml +79 -0
- qwak_sdk/inner/tools/tracking.py +47 -0
- qwak_sdk/main.py +9 -0
- qwak_sdk/tools/__init__.py +0 -0
- qwak_sdk/tools/colors.py +13 -0
- qwak_sdk/tools/files.py +63 -0
- qwak_sdk/tools/log_handling.py +159 -0
- qwak_sdk/tools/utils.py +42 -0
- qwak_sdk-0.5.102.dist-info/METADATA +51 -0
- qwak_sdk-0.5.102.dist-info/RECORD +328 -0
- qwak_sdk-0.5.102.dist-info/WHEEL +4 -0
- qwak_sdk-0.5.102.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from _qwak_proto.qwak.deployment.deployment_pb2 import DeploymentSize, MemoryUnit
|
|
4
|
+
from _qwak_proto.qwak.user_application.common.v0.resources_pb2 import (
|
|
5
|
+
ClientPodComputeResources,
|
|
6
|
+
CpuResources,
|
|
7
|
+
GpuResources,
|
|
8
|
+
PodComputeResourceTemplateSpec,
|
|
9
|
+
)
|
|
10
|
+
from qwak.clients.administration.eco_system.client import EcosystemClient
|
|
11
|
+
from qwak.clients.instance_template.client import InstanceTemplateManagementClient
|
|
12
|
+
from qwak.exceptions import QwakException
|
|
13
|
+
from qwak.inner.instance_template.verify_template_id import verify_template_id
|
|
14
|
+
from qwak.inner.provider import Provider
|
|
15
|
+
|
|
16
|
+
from qwak_sdk.commands.models.deployments.deploy._logic.deploy_config import (
|
|
17
|
+
DeployConfig,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def deployment_size_from_deploy_config(
|
|
22
|
+
deploy_config: DeployConfig,
|
|
23
|
+
instance_template_client: InstanceTemplateManagementClient,
|
|
24
|
+
ecosystem_client: EcosystemClient,
|
|
25
|
+
) -> DeploymentSize:
|
|
26
|
+
if deploy_config.resources.instance_size:
|
|
27
|
+
deploy_config.resources.instance_size = (
|
|
28
|
+
deploy_config.resources.instance_size.lower()
|
|
29
|
+
)
|
|
30
|
+
account_details = ecosystem_client.get_account_details()
|
|
31
|
+
if deploy_config.environments:
|
|
32
|
+
environments_config = list(
|
|
33
|
+
ecosystem_client.get_environments_names_to_details(
|
|
34
|
+
deploy_config.environments
|
|
35
|
+
).values()
|
|
36
|
+
)
|
|
37
|
+
else:
|
|
38
|
+
environments_config = [
|
|
39
|
+
account_details.environment_by_id[
|
|
40
|
+
account_details.default_environment_id
|
|
41
|
+
]
|
|
42
|
+
]
|
|
43
|
+
for environment_config in environments_config:
|
|
44
|
+
provider = __get_provider(environment_config)
|
|
45
|
+
try:
|
|
46
|
+
verify_template_id(
|
|
47
|
+
deploy_config.resources.instance_size,
|
|
48
|
+
instance_template_client,
|
|
49
|
+
provider=provider,
|
|
50
|
+
)
|
|
51
|
+
except QwakException as e:
|
|
52
|
+
raise QwakException(
|
|
53
|
+
f"Error with template {deploy_config.resources.instance_size} for environment {environment_config.name}: {e.message}"
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
return DeploymentSize(
|
|
57
|
+
number_of_pods=deploy_config.resources.pods,
|
|
58
|
+
client_pod_compute_resources=ClientPodComputeResources(
|
|
59
|
+
template_spec=PodComputeResourceTemplateSpec(
|
|
60
|
+
template_id=deploy_config.resources.instance_size
|
|
61
|
+
)
|
|
62
|
+
),
|
|
63
|
+
)
|
|
64
|
+
elif deploy_config.resources.gpu_type:
|
|
65
|
+
return DeploymentSize(
|
|
66
|
+
number_of_pods=deploy_config.resources.pods,
|
|
67
|
+
client_pod_compute_resources=ClientPodComputeResources(
|
|
68
|
+
gpu_resources=GpuResources(
|
|
69
|
+
gpu_type=deploy_config.resources.gpu_type,
|
|
70
|
+
gpu_amount=deploy_config.resources.gpu_amount,
|
|
71
|
+
)
|
|
72
|
+
),
|
|
73
|
+
)
|
|
74
|
+
else:
|
|
75
|
+
return DeploymentSize(
|
|
76
|
+
number_of_pods=deploy_config.resources.pods,
|
|
77
|
+
client_pod_compute_resources=ClientPodComputeResources(
|
|
78
|
+
cpu_resources=CpuResources(
|
|
79
|
+
cpu=deploy_config.resources.cpus,
|
|
80
|
+
memory_amount=deploy_config.resources.memory,
|
|
81
|
+
memory_units=MemoryUnit.MIB,
|
|
82
|
+
)
|
|
83
|
+
),
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def __get_provider(environment_config):
|
|
88
|
+
provider = None
|
|
89
|
+
cloud_type = environment_config.configuration.cloud_configuration.WhichOneof(
|
|
90
|
+
"configuration"
|
|
91
|
+
)
|
|
92
|
+
if cloud_type == "aws_cloud_configuration":
|
|
93
|
+
provider = Provider.AWS
|
|
94
|
+
elif cloud_type == "gcp_cloud_configuration":
|
|
95
|
+
provider = Provider.GCP
|
|
96
|
+
return provider
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from _qwak_proto.qwak.build.v1.build_pb2 import SUCCESSFUL
|
|
2
|
+
from qwak.clients.build_orchestrator import BuildOrchestratorClient
|
|
3
|
+
from qwak.clients.model_management.client import ModelsManagementClient
|
|
4
|
+
from qwak.exceptions import QwakException
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def get_latest_successful_build_from_model(model_id: str) -> str:
|
|
8
|
+
"""Get the latest successful build from model
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
model_id: Model id to search build for.
|
|
12
|
+
|
|
13
|
+
Returns:
|
|
14
|
+
str: Latest build id.
|
|
15
|
+
|
|
16
|
+
Raises:
|
|
17
|
+
QwakException: if no successful build exists in model.
|
|
18
|
+
"""
|
|
19
|
+
model = ModelsManagementClient().get_model(model_id)
|
|
20
|
+
model_uuid = model.uuid
|
|
21
|
+
all_builds = BuildOrchestratorClient().list_builds(model_uuid).build
|
|
22
|
+
builds = [build for build in all_builds if build.build_status == SUCCESSFUL]
|
|
23
|
+
builds.sort(key=lambda r: r.audit.created_at.seconds)
|
|
24
|
+
|
|
25
|
+
if not builds:
|
|
26
|
+
raise QwakException(f"Unable to find successful build for model {model_id}")
|
|
27
|
+
|
|
28
|
+
return builds[-1].buildId
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
|
|
3
|
+
from _qwak_proto.qwak.ecosystem.v0.ecosystem_runtime_service_pb2 import (
|
|
4
|
+
GetCloudCredentialsParameters,
|
|
5
|
+
GetCloudCredentialsRequest,
|
|
6
|
+
PermissionSet,
|
|
7
|
+
PullModelsContainerRegistry,
|
|
8
|
+
)
|
|
9
|
+
from google.protobuf.duration_pb2 import Duration
|
|
10
|
+
from qwak.clients.administration.eco_system.client import EcosystemClient
|
|
11
|
+
from qwak.clients.build_orchestrator import BuildOrchestratorClient
|
|
12
|
+
from qwak.exceptions import QwakException
|
|
13
|
+
from rich.console import Console
|
|
14
|
+
from rich.layout import Layout
|
|
15
|
+
from rich.panel import Panel
|
|
16
|
+
from rich.progress import Progress
|
|
17
|
+
|
|
18
|
+
from qwak_sdk.commands.models.deployments.deploy._logic.deploy_config import (
|
|
19
|
+
DeployConfig,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
tasks = {}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def local_deploy(config: DeployConfig):
|
|
26
|
+
try:
|
|
27
|
+
import docker
|
|
28
|
+
except ImportError:
|
|
29
|
+
raise QwakException(
|
|
30
|
+
"Error: 'docker' package is required to for local model deployment."
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
console = Console()
|
|
34
|
+
console.print(Panel(f"Deploying model {config.model_id} locally", style="green"))
|
|
35
|
+
|
|
36
|
+
client = docker.from_env()
|
|
37
|
+
build_image = _get_build_image(config)
|
|
38
|
+
|
|
39
|
+
if not client.images.list(name=build_image):
|
|
40
|
+
console.print(
|
|
41
|
+
"Pulling serving image from Qwak's remote repository. Might take a few minutes...",
|
|
42
|
+
style="yellow",
|
|
43
|
+
)
|
|
44
|
+
_docker_login(client)
|
|
45
|
+
_image_pull(client, build_image)
|
|
46
|
+
|
|
47
|
+
try:
|
|
48
|
+
container = start_local_qwak_container(build_image, client, config)
|
|
49
|
+
container.reload()
|
|
50
|
+
host_port = container.ports.get("5000/tcp")[0]["HostPort"]
|
|
51
|
+
|
|
52
|
+
layout = example_usage_layout(host_port)
|
|
53
|
+
console.print(layout)
|
|
54
|
+
|
|
55
|
+
for line in container.logs(stream=True):
|
|
56
|
+
console.print(str(line.strip().decode()), style="blue")
|
|
57
|
+
|
|
58
|
+
except KeyboardInterrupt:
|
|
59
|
+
console.print(Panel("Stopping container...", style="red"))
|
|
60
|
+
container.stop()
|
|
61
|
+
container.remove()
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def example_usage_layout(host_port: str):
|
|
65
|
+
layout = Layout(size=6)
|
|
66
|
+
layout.split_row(
|
|
67
|
+
Layout(name="left"),
|
|
68
|
+
Layout(name="right"),
|
|
69
|
+
)
|
|
70
|
+
layout["left"].update(
|
|
71
|
+
Panel(
|
|
72
|
+
f"[bold]cURL usage:[bold]\n\n"
|
|
73
|
+
f"curl --location\n"
|
|
74
|
+
f"--request POST http://localhost:{host_port}/predict\n"
|
|
75
|
+
f"--header 'Content-Type: application/json'\n"
|
|
76
|
+
f"--data '...'",
|
|
77
|
+
style="green",
|
|
78
|
+
)
|
|
79
|
+
)
|
|
80
|
+
layout["right"].update(
|
|
81
|
+
Panel(
|
|
82
|
+
f"[bold]Python client usage:[bold]\n\n"
|
|
83
|
+
f"from qwak_inference import RealtimeClient\n\nfeature_vector=[...]\n"
|
|
84
|
+
f"client = RealTimeClient(model_api='http://localhost:{host_port}/predict')\n"
|
|
85
|
+
f"client.predict(feature_vector)",
|
|
86
|
+
style="green",
|
|
87
|
+
)
|
|
88
|
+
)
|
|
89
|
+
return layout
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def start_local_qwak_container(build_image: str, docker_client, config: DeployConfig):
|
|
93
|
+
return docker_client.containers.run(
|
|
94
|
+
build_image,
|
|
95
|
+
command=["bentoml", "serve-gunicorn", "./"],
|
|
96
|
+
entrypoint="./docker-entrypoint.sh",
|
|
97
|
+
environment=[
|
|
98
|
+
"BENTOML_GUNICORN_WORKERS=2",
|
|
99
|
+
"QWAK_DEBUG_MODE=True",
|
|
100
|
+
f"QWAK_MODEL_ID={config.model_id}",
|
|
101
|
+
"BENTOML_DO_NOT_TRACK=True",
|
|
102
|
+
"PYTHONPATH=/qwak/model_dir:/qwak/model_dir/main:$PYTHONPATH",
|
|
103
|
+
f"QWAK_BUILD_ID={config.build_id}",
|
|
104
|
+
"BUNDLE_PATH=/home/bentoml/bundle",
|
|
105
|
+
"BENTOML_HOME=/home/bentoml/",
|
|
106
|
+
],
|
|
107
|
+
stream=True,
|
|
108
|
+
detach=True,
|
|
109
|
+
publish_all_ports=True,
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def _get_build_image(config: DeployConfig):
|
|
114
|
+
return (
|
|
115
|
+
BuildOrchestratorClient().get_build(config.build_id).build.build_destined_image
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def _show_progress(line, progress):
|
|
120
|
+
if line["status"] == "Downloading":
|
|
121
|
+
idx = f'[red][Download {line["id"]}]'
|
|
122
|
+
elif line["status"] == "Extracting":
|
|
123
|
+
idx = f'[green][Extract {line["id"]}]'
|
|
124
|
+
else:
|
|
125
|
+
# skip other statuses
|
|
126
|
+
return
|
|
127
|
+
|
|
128
|
+
if idx not in tasks.keys():
|
|
129
|
+
tasks[idx] = progress.add_task(f"{idx}", total=line["progressDetail"]["total"])
|
|
130
|
+
else:
|
|
131
|
+
progress.update(tasks[idx], completed=line["progressDetail"]["current"])
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def _image_pull(docker_client, image_name: str):
|
|
135
|
+
with Progress() as progress:
|
|
136
|
+
resp = docker_client.api.pull(image_name, stream=True, decode=True)
|
|
137
|
+
for line in resp:
|
|
138
|
+
_show_progress(line, progress)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def _docker_login(docker_client):
|
|
142
|
+
try:
|
|
143
|
+
import boto3
|
|
144
|
+
except ImportError:
|
|
145
|
+
raise QwakException(
|
|
146
|
+
"Error: The 'boto3' package is necessary for local model deployment. Install it directly or by running"
|
|
147
|
+
" 'pip install qwak[local-deployment]'"
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
# TODO: block if not an AWS based container registry
|
|
151
|
+
credentials = _get_aws_credentials()
|
|
152
|
+
|
|
153
|
+
aws_credentials = credentials.cloud_credentials.aws_temporary_credentials
|
|
154
|
+
ecr_client = boto3.Session(
|
|
155
|
+
aws_access_key_id=aws_credentials.access_key_id,
|
|
156
|
+
aws_secret_access_key=aws_credentials.secret_access_key,
|
|
157
|
+
aws_session_token=aws_credentials.session_token,
|
|
158
|
+
region_name=aws_credentials.region,
|
|
159
|
+
).client("ecr")
|
|
160
|
+
|
|
161
|
+
ecr_credentials = ecr_client.get_authorization_token()["authorizationData"][0]
|
|
162
|
+
|
|
163
|
+
try:
|
|
164
|
+
docker_client.login(
|
|
165
|
+
username="AWS",
|
|
166
|
+
registry=ecr_credentials["proxyEndpoint"],
|
|
167
|
+
password=base64.b64decode(ecr_credentials["authorizationToken"])
|
|
168
|
+
.replace(b"AWS:", b"")
|
|
169
|
+
.decode("utf-8"),
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
except Exception as e:
|
|
173
|
+
raise QwakException(f"Failed to login to Qwak's container registry: {e}")
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def _get_aws_credentials():
|
|
177
|
+
try:
|
|
178
|
+
eco_client = EcosystemClient()
|
|
179
|
+
credentials = eco_client.get_cloud_credentials(
|
|
180
|
+
request=GetCloudCredentialsRequest(
|
|
181
|
+
parameters=GetCloudCredentialsParameters(
|
|
182
|
+
duration=Duration(seconds=60 * 60, nanos=0), # 6 hours
|
|
183
|
+
permission_set=PermissionSet(
|
|
184
|
+
pull_models_container_registry=PullModelsContainerRegistry()
|
|
185
|
+
),
|
|
186
|
+
)
|
|
187
|
+
)
|
|
188
|
+
)
|
|
189
|
+
return credentials
|
|
190
|
+
except Exception as e:
|
|
191
|
+
raise QwakException(
|
|
192
|
+
f"Failed to get credentials to pull image from Qwak's container registry: {e}."
|
|
193
|
+
)
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from _qwak_proto.qwak.deployment.deployment_pb2 import AdvancedDeploymentOptions
|
|
2
|
+
|
|
3
|
+
from qwak_sdk.commands.models.deployments.deploy._logic.deploy_config import (
|
|
4
|
+
DeployConfig,
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def batch_advanced_deployment_options_from_deploy_config(
|
|
9
|
+
deploy_config: DeployConfig,
|
|
10
|
+
) -> AdvancedDeploymentOptions:
|
|
11
|
+
return AdvancedDeploymentOptions(
|
|
12
|
+
custom_iam_role_arn=deploy_config.advanced_options.iam_role_arn,
|
|
13
|
+
purchase_option=deploy_config.advanced_options.purchase_option,
|
|
14
|
+
service_account_key_secret_name=deploy_config.advanced_options.service_account_key_secret_name,
|
|
15
|
+
)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from _qwak_proto.qwak.deployment.deployment_pb2 import KubeDeploymentType
|
|
2
|
+
from _qwak_proto.qwak.deployment.deployment_service_pb2 import DeployModelResponse
|
|
3
|
+
|
|
4
|
+
from qwak_sdk.commands.models.deployments.deploy._logic.base_deploy_executor import (
|
|
5
|
+
BaseDeployExecutor,
|
|
6
|
+
)
|
|
7
|
+
from qwak_sdk.commands.models.deployments.deploy._logic.deployment_message_helpers import (
|
|
8
|
+
get_env_to_deployment_message,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class BatchDeployExecutor(BaseDeployExecutor):
|
|
13
|
+
def deploy(self) -> DeployModelResponse:
|
|
14
|
+
env_deployment_messages = get_env_to_deployment_message(
|
|
15
|
+
self.config,
|
|
16
|
+
KubeDeploymentType.BATCH,
|
|
17
|
+
self.ecosystem_client,
|
|
18
|
+
self.instance_template_client,
|
|
19
|
+
)
|
|
20
|
+
return self.deploy_client.deploy_model(
|
|
21
|
+
model_id=self.config.model_id,
|
|
22
|
+
build_id=self.config.build_id,
|
|
23
|
+
env_deployment_messages=env_deployment_messages,
|
|
24
|
+
)
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import click
|
|
2
|
+
from qwak.inner.const import QwakConstants
|
|
3
|
+
from qwak.tools.logger.logger import set_qwak_logger_stdout_verbosity_level
|
|
4
|
+
|
|
5
|
+
from qwak_sdk.commands.models.deployments.deploy._logic.deploy_config import (
|
|
6
|
+
DeployConfig,
|
|
7
|
+
PurchaseOption,
|
|
8
|
+
)
|
|
9
|
+
from qwak_sdk.commands.models.deployments.deploy._logic.deployment_response_handler import (
|
|
10
|
+
client_deployment,
|
|
11
|
+
)
|
|
12
|
+
from qwak_sdk.commands.models.deployments.deploy.batch._logic.deploy_executor import (
|
|
13
|
+
BatchDeployExecutor,
|
|
14
|
+
)
|
|
15
|
+
from qwak_sdk.inner.tools.cli_tools import DeprecatedOption, QwakCommand
|
|
16
|
+
from qwak_sdk.inner.tools.config_handler import config_handler
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@click.command("batch", help="Deploy batch model.", cls=QwakCommand)
|
|
20
|
+
@click.option(
|
|
21
|
+
"--build-id",
|
|
22
|
+
help="Build ID, If not specified latest successful build will deployed.",
|
|
23
|
+
type=str,
|
|
24
|
+
)
|
|
25
|
+
@click.option("--model-id", help="Model ID", type=str, required=True)
|
|
26
|
+
@click.option(
|
|
27
|
+
"--pods",
|
|
28
|
+
"--replicas",
|
|
29
|
+
type=int,
|
|
30
|
+
help="Number of pods to deploy.",
|
|
31
|
+
deprecated=["--pods"],
|
|
32
|
+
preferred="--replicas",
|
|
33
|
+
cls=DeprecatedOption,
|
|
34
|
+
)
|
|
35
|
+
@click.option(
|
|
36
|
+
"--cpus",
|
|
37
|
+
type=float,
|
|
38
|
+
help="Number of CPU cores, can be fraction of a core (e.g. 0.4).",
|
|
39
|
+
)
|
|
40
|
+
@click.option(
|
|
41
|
+
"--memory",
|
|
42
|
+
type=int,
|
|
43
|
+
help="Memory amount in Mib (e.g. 256).",
|
|
44
|
+
)
|
|
45
|
+
@click.option(
|
|
46
|
+
"--gpu-type",
|
|
47
|
+
metavar="NAME",
|
|
48
|
+
required=False,
|
|
49
|
+
help=f"Type of GPU to use on the deployments ({', '.join([x for x in QwakConstants.GPU_TYPES])}).",
|
|
50
|
+
type=click.STRING,
|
|
51
|
+
)
|
|
52
|
+
@click.option(
|
|
53
|
+
"--gpu-amount",
|
|
54
|
+
metavar="NAME",
|
|
55
|
+
required=False,
|
|
56
|
+
type=int,
|
|
57
|
+
help="Amount of GPU to use on the deployments.",
|
|
58
|
+
)
|
|
59
|
+
@click.option(
|
|
60
|
+
"--iam-role-arn",
|
|
61
|
+
type=str,
|
|
62
|
+
help="Custom IAM Role ARN.",
|
|
63
|
+
)
|
|
64
|
+
@click.option(
|
|
65
|
+
"--service-account-key-secret-name",
|
|
66
|
+
type=str,
|
|
67
|
+
help="Custom service account for Gcp.",
|
|
68
|
+
)
|
|
69
|
+
@click.option(
|
|
70
|
+
"--sync",
|
|
71
|
+
is_flag=True,
|
|
72
|
+
default=False,
|
|
73
|
+
help="Waiting for deployments to be ready",
|
|
74
|
+
)
|
|
75
|
+
@click.option(
|
|
76
|
+
"-v",
|
|
77
|
+
"--verbose",
|
|
78
|
+
count=True,
|
|
79
|
+
help="Log verbosity level - v: INFO, vv: DEBUG [default: WARNING]",
|
|
80
|
+
)
|
|
81
|
+
@click.option(
|
|
82
|
+
"-f",
|
|
83
|
+
"--from-file",
|
|
84
|
+
help="Deploy by run_config file, Command arguments will overwrite any run_config.",
|
|
85
|
+
required=False,
|
|
86
|
+
type=click.Path(exists=True, resolve_path=True, dir_okay=False),
|
|
87
|
+
)
|
|
88
|
+
@click.option(
|
|
89
|
+
"--out-conf",
|
|
90
|
+
help="Extract deploy conf from commands arguments, the commands will not run it wil only output valid yaml "
|
|
91
|
+
"structure",
|
|
92
|
+
default=False,
|
|
93
|
+
is_flag=True,
|
|
94
|
+
)
|
|
95
|
+
@click.option(
|
|
96
|
+
"--purchase-option",
|
|
97
|
+
required=False,
|
|
98
|
+
type=click.Choice([i.value for i in PurchaseOption], case_sensitive=False),
|
|
99
|
+
help="Indicate the instance deployments type, whether it is spot/ondemand. Default is spot",
|
|
100
|
+
)
|
|
101
|
+
@click.option(
|
|
102
|
+
"--instance",
|
|
103
|
+
required=False,
|
|
104
|
+
type=str,
|
|
105
|
+
help="The instance size to deploy on - 'small', 'medium', 'large', etc...",
|
|
106
|
+
default=None,
|
|
107
|
+
)
|
|
108
|
+
@click.option(
|
|
109
|
+
"--environment-name",
|
|
110
|
+
required=False,
|
|
111
|
+
type=str,
|
|
112
|
+
help="Environment to deploy on (if not specified uses your default environment",
|
|
113
|
+
multiple=True,
|
|
114
|
+
)
|
|
115
|
+
def batch(verbose: bool, from_file: str, out_conf: bool, sync: bool, **kwargs):
|
|
116
|
+
set_qwak_logger_stdout_verbosity_level(verbose + 1)
|
|
117
|
+
config: DeployConfig = config_handler(
|
|
118
|
+
config=DeployConfig,
|
|
119
|
+
from_file=from_file,
|
|
120
|
+
out_conf=out_conf,
|
|
121
|
+
sections=("batch",),
|
|
122
|
+
**kwargs,
|
|
123
|
+
)
|
|
124
|
+
if not out_conf:
|
|
125
|
+
deploy_executor = BatchDeployExecutor(config)
|
|
126
|
+
client_deployment(deploy=deploy_executor, sync=sync)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from click import group
|
|
2
|
+
|
|
3
|
+
from qwak_sdk.commands.models.deployments.deploy.batch.ui import batch
|
|
4
|
+
from qwak_sdk.commands.models.deployments.deploy.realtime.ui import realtime
|
|
5
|
+
from qwak_sdk.commands.models.deployments.deploy.streaming.ui import stream
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@group(
|
|
9
|
+
name="deploy",
|
|
10
|
+
help="Model deployments",
|
|
11
|
+
)
|
|
12
|
+
def deploy_group():
|
|
13
|
+
# Click group injection
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
deploy_group.add_command(realtime, "realtime")
|
|
18
|
+
deploy_group.add_command(stream, "stream")
|
|
19
|
+
deploy_group.add_command(batch, "batch")
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from _qwak_proto.qwak.deployment.deployment_pb2 import AdvancedDeploymentOptions
|
|
2
|
+
from google.protobuf.wrappers_pb2 import BoolValue
|
|
3
|
+
|
|
4
|
+
from qwak_sdk.commands.models.deployments.deploy._logic.deploy_config import (
|
|
5
|
+
DeployConfig,
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def realtime_advanced_deployment_options_from_deploy_config(
|
|
10
|
+
deploy_config: DeployConfig,
|
|
11
|
+
) -> AdvancedDeploymentOptions:
|
|
12
|
+
return AdvancedDeploymentOptions(
|
|
13
|
+
number_of_http_server_workers=deploy_config.realtime.workers,
|
|
14
|
+
http_request_timeout_ms=deploy_config.realtime.timeout,
|
|
15
|
+
daemon_mode=BoolValue(value=deploy_config.realtime.daemon_mode),
|
|
16
|
+
max_batch_size=deploy_config.realtime.max_batch_size,
|
|
17
|
+
custom_iam_role_arn=deploy_config.advanced_options.iam_role_arn,
|
|
18
|
+
purchase_option=deploy_config.advanced_options.purchase_option,
|
|
19
|
+
deployment_process_timeout_limit=deploy_config.realtime.deployment_timeout,
|
|
20
|
+
service_account_key_secret_name=deploy_config.advanced_options.service_account_key_secret_name,
|
|
21
|
+
)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from _qwak_proto.qwak.deployment.deployment_pb2 import KubeDeploymentType
|
|
2
|
+
from _qwak_proto.qwak.deployment.deployment_service_pb2 import DeployModelResponse
|
|
3
|
+
|
|
4
|
+
from qwak_sdk.commands.models.deployments.deploy._logic.base_deploy_executor import (
|
|
5
|
+
BaseDeployExecutor,
|
|
6
|
+
)
|
|
7
|
+
from qwak_sdk.commands.models.deployments.deploy._logic.deployment_message_helpers import (
|
|
8
|
+
get_env_to_deployment_message,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class RealtimeDeployExecutor(BaseDeployExecutor):
|
|
13
|
+
def deploy(self) -> DeployModelResponse:
|
|
14
|
+
env_deployment_messages = get_env_to_deployment_message(
|
|
15
|
+
self.config,
|
|
16
|
+
KubeDeploymentType.ONLINE,
|
|
17
|
+
self.ecosystem_client,
|
|
18
|
+
self.instance_template_client,
|
|
19
|
+
)
|
|
20
|
+
return self.deploy_client.deploy_model(
|
|
21
|
+
model_id=self.config.model_id,
|
|
22
|
+
build_id=self.config.build_id,
|
|
23
|
+
env_deployment_messages=env_deployment_messages,
|
|
24
|
+
)
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Dict, List
|
|
4
|
+
|
|
5
|
+
from _qwak_proto.qwak.auto_scaling.v1.auto_scaling_pb2 import AutoScalingConfig
|
|
6
|
+
from _qwak_proto.qwak.deployment.deployment_pb2 import (
|
|
7
|
+
RealTimeConfig,
|
|
8
|
+
ServingStrategy,
|
|
9
|
+
TrafficConfig,
|
|
10
|
+
)
|
|
11
|
+
from _qwak_proto.qwak.ecosystem.v0.ecosystem_pb2 import UserContextEnvironmentDetails
|
|
12
|
+
from qwak.exceptions import QwakException
|
|
13
|
+
|
|
14
|
+
from qwak_sdk.commands.audience._logic.config.v1.audience_config import AudienceConfig
|
|
15
|
+
from qwak_sdk.commands.models.deployments.deploy._logic.deploy_config import (
|
|
16
|
+
DeployConfig,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def create_realtime_serving_strategy(
|
|
21
|
+
auto_scaling: AutoScalingConfig,
|
|
22
|
+
audiences: List[AudienceConfig],
|
|
23
|
+
fallback_variation: str,
|
|
24
|
+
variation_name: str,
|
|
25
|
+
variation_protected_state: bool = False,
|
|
26
|
+
) -> ServingStrategy:
|
|
27
|
+
return ServingStrategy(
|
|
28
|
+
realtime_config=(
|
|
29
|
+
RealTimeConfig(
|
|
30
|
+
auto_scaling_config=auto_scaling,
|
|
31
|
+
traffic_config=TrafficConfig(
|
|
32
|
+
selected_variation_name=variation_name,
|
|
33
|
+
audience_routes_entries=[
|
|
34
|
+
audience.to_audience_route_entry(index)
|
|
35
|
+
for index, audience in enumerate(audiences)
|
|
36
|
+
],
|
|
37
|
+
fallback_variation=fallback_variation,
|
|
38
|
+
selected_variation_protect_state=variation_protected_state,
|
|
39
|
+
),
|
|
40
|
+
)
|
|
41
|
+
)
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def create_realtime_serving_strategy_from_deploy_config(
|
|
46
|
+
deploy_config: DeployConfig,
|
|
47
|
+
environment_name_to_config: Dict[str, UserContextEnvironmentDetails],
|
|
48
|
+
) -> Dict[str, ServingStrategy]:
|
|
49
|
+
serving_strategies = {}
|
|
50
|
+
errors = []
|
|
51
|
+
variation_name = deploy_config.realtime.variation_name or "default"
|
|
52
|
+
variation_protected_state = deploy_config.realtime.variation_protected_state
|
|
53
|
+
fallback_variation = deploy_config.realtime.fallback_variation
|
|
54
|
+
auto_scaling = (
|
|
55
|
+
deploy_config.auto_scaling.to_autoscaling_api()
|
|
56
|
+
if deploy_config.auto_scaling
|
|
57
|
+
else None
|
|
58
|
+
)
|
|
59
|
+
for env_name, env_config in environment_name_to_config.items():
|
|
60
|
+
try:
|
|
61
|
+
serving_strategies[env_config.id] = create_realtime_serving_strategy(
|
|
62
|
+
auto_scaling,
|
|
63
|
+
deploy_config.realtime.audiences,
|
|
64
|
+
fallback_variation,
|
|
65
|
+
variation_name,
|
|
66
|
+
variation_protected_state,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
except QwakException as e:
|
|
70
|
+
errors.append(e.message)
|
|
71
|
+
|
|
72
|
+
if errors:
|
|
73
|
+
raise QwakException("\n".join(errors))
|
|
74
|
+
|
|
75
|
+
return serving_strategies
|