qwak-sdk 0.1.0__py3-none-any.whl → 0.2.20rc0__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.
- qwak_sdk/__init__.py +9 -0
- qwak_sdk/cli.py +51 -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/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 +16 -0
- qwak_sdk/commands/audience/_logic/config/parser.py +28 -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 +60 -0
- qwak_sdk/commands/audience/_logic/config/v1/config_v1.py +24 -0
- qwak_sdk/commands/audience/_logic/config/v1/route_config.py +14 -0
- qwak_sdk/commands/audience/_logic/config/v1/spec.py +11 -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 +100 -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 +8 -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/delete/__init__.py +0 -0
- qwak_sdk/commands/feature_store/delete/_logic.py +52 -0
- qwak_sdk/commands/feature_store/delete/ui.py +40 -0
- qwak_sdk/commands/feature_store/feature_store_command_group.py +25 -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 +289 -0
- qwak_sdk/commands/feature_store/register/ui.py +105 -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 +32 -0
- qwak_sdk/commands/models/__init__.py +0 -0
- qwak_sdk/commands/models/_logic/__init__.py +0 -0
- qwak_sdk/commands/models/_logic/variations.py +55 -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 +68 -0
- qwak_sdk/commands/models/build/_logic/client_logs/__init__.py +0 -0
- qwak_sdk/commands/models/build/_logic/client_logs/build_run_handlers.py +189 -0
- qwak_sdk/commands/models/build/_logic/client_logs/cli_ui.py +125 -0
- qwak_sdk/commands/models/build/_logic/client_logs/logger.py +88 -0
- qwak_sdk/commands/models/build/_logic/client_logs/messages.py +40 -0
- qwak_sdk/commands/models/build/_logic/client_logs/notifier_impl.py +49 -0
- qwak_sdk/commands/models/build/_logic/client_logs/spinner.py +14 -0
- qwak_sdk/commands/models/build/_logic/client_logs/time_source.py +37 -0
- qwak_sdk/commands/models/build/_logic/client_logs/utils.py +12 -0
- qwak_sdk/commands/models/build/_logic/config/config_v1.py +253 -0
- qwak_sdk/commands/models/build/_logic/constant/host_resource.py +4 -0
- qwak_sdk/commands/models/build/_logic/constant/step_description.py +29 -0
- qwak_sdk/commands/models/build/_logic/constant/temp_dir.py +2 -0
- qwak_sdk/commands/models/build/_logic/constant/upload_tag.py +5 -0
- qwak_sdk/commands/models/build/_logic/context.py +62 -0
- qwak_sdk/commands/models/build/_logic/interface/__init__.py +0 -0
- qwak_sdk/commands/models/build/_logic/interface/notifier_interface.py +29 -0
- qwak_sdk/commands/models/build/_logic/interface/step_inteface.py +29 -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 +14 -0
- qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/fetch_model_step/__init__.py +0 -0
- qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/fetch_model_step/fetch_model_step.py +42 -0
- qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/fetch_model_step/fetch_strategy_manager/__init__.py +0 -0
- qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/fetch_model_step/fetch_strategy_manager/common.py +33 -0
- qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/fetch_model_step/fetch_strategy_manager/fetch_strategy_manager.py +60 -0
- qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/fetch_model_step/fetch_strategy_manager/strategy/__init__.py +0 -0
- qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/fetch_model_step/fetch_strategy_manager/strategy/folder/__init__.py +0 -0
- qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/fetch_model_step/fetch_strategy_manager/strategy/folder/folder_strategy.py +73 -0
- qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/fetch_model_step/fetch_strategy_manager/strategy/git/__init__.py +0 -0
- qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/fetch_model_step/fetch_strategy_manager/strategy/git/git_strategy.py +149 -0
- qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/fetch_model_step/fetch_strategy_manager/strategy/strategy.py +69 -0
- qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/fetch_model_step/fetch_strategy_manager/strategy/zip/__init__.py +0 -0
- qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/fetch_model_step/fetch_strategy_manager/strategy/zip/zip_strategy.py +64 -0
- qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/post_fetch_validation_step.py +117 -0
- qwak_sdk/commands/models/build/_logic/phase/a_fetch_model_code/pre_fetch_validation_step.py +135 -0
- qwak_sdk/commands/models/build/_logic/phase/b_remote_register_qwak_build/__init__.py +11 -0
- qwak_sdk/commands/models/build/_logic/phase/b_remote_register_qwak_build/cleanup_step.py +20 -0
- qwak_sdk/commands/models/build/_logic/phase/b_remote_register_qwak_build/start_remote_build_step.py +42 -0
- qwak_sdk/commands/models/build/_logic/phase/b_remote_register_qwak_build/upload_step.py +349 -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 +54 -0
- qwak_sdk/commands/models/build/_logic/phase/c_deploy/deploy_build.py +44 -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 +37 -0
- qwak_sdk/commands/models/build/_logic/util/text.py +9 -0
- qwak_sdk/commands/models/build/ui.py +241 -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 +30 -0
- qwak_sdk/commands/models/create/__init__.py +0 -0
- qwak_sdk/commands/models/create/_logic.py +35 -0
- qwak_sdk/commands/models/create/ui.py +27 -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 +16 -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 +64 -0
- qwak_sdk/commands/models/deployments/deploy/_logic/deploy_config.py +241 -0
- qwak_sdk/commands/models/deployments/deploy/_logic/deployment.py +405 -0
- qwak_sdk/commands/models/deployments/deploy/_logic/deployment_message_helpers.py +98 -0
- qwak_sdk/commands/models/deployments/deploy/_logic/deployment_response_handler.py +154 -0
- qwak_sdk/commands/models/deployments/deploy/_logic/deployment_size_mapper.py +21 -0
- qwak_sdk/commands/models/deployments/deploy/_logic/get_latest_successful_build.py +31 -0
- qwak_sdk/commands/models/deployments/deploy/_logic/variations.py +79 -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 +14 -0
- qwak_sdk/commands/models/deployments/deploy/batch/_logic/deploy_executor.py +24 -0
- qwak_sdk/commands/models/deployments/deploy/batch/ui.py +104 -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 +20 -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 +105 -0
- qwak_sdk/commands/models/deployments/deploy/realtime/ui.py +179 -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 +196 -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 +176 -0
- qwak_sdk/commands/models/deployments/undeploy/_logic/variations.py +74 -0
- qwak_sdk/commands/models/deployments/undeploy/ui.py +78 -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 +16 -0
- qwak_sdk/commands/models/executions/start/ui.py +176 -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 +10 -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 +10 -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 +18 -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 +31 -0
- qwak_sdk/commands/models/models_command_group.py +36 -0
- qwak_sdk/commands/models/runtime/__init__.py +0 -0
- qwak_sdk/commands/models/runtime/feedback/__init__.py +0 -0
- qwak_sdk/commands/models/runtime/feedback/_logic.py +81 -0
- qwak_sdk/commands/models/runtime/feedback/ui.py +45 -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 +21 -0
- qwak_sdk/commands/models/runtime/traffic_update/__init__.py +0 -0
- qwak_sdk/commands/models/runtime/traffic_update/_logic/__init__.py +0 -0
- qwak_sdk/commands/models/runtime/traffic_update/_logic/execute_runtime_update_traffic.py +54 -0
- qwak_sdk/commands/models/runtime/traffic_update/_logic/variations.py +84 -0
- qwak_sdk/commands/models/runtime/traffic_update/ui.py +37 -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 +6 -0
- qwak_sdk/commands/projects/create/ui.py +21 -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 +15 -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 +36 -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/common/__init__.py +0 -0
- qwak_sdk/common/run_config/__init__.py +22 -0
- qwak_sdk/common/run_config/base.py +101 -0
- qwak_sdk/common/run_config/utils.py +249 -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_general_build_exception.py +13 -0
- qwak_sdk/exceptions/qwak_remote_build_failed.py +5 -0
- qwak_sdk/exceptions/qwak_resource_not_found.py +2 -0
- qwak_sdk/exceptions/qwak_suggestion_exception.py +27 -0
- qwak_sdk/inner/__init__.py +0 -0
- qwak_sdk/inner/file_registry.py +97 -0
- qwak_sdk/inner/tools/__init__.py +0 -0
- qwak_sdk/inner/tools/cli_tools.py +159 -0
- qwak_sdk/inner/tools/config_handler.py +18 -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 +9 -0
- qwak_sdk/tools/log_handling.py +146 -0
- qwak_sdk/tools/utils.py +46 -0
- qwak_sdk-0.2.20rc0.dist-info/METADATA +42 -0
- qwak_sdk-0.2.20rc0.dist-info/RECORD +302 -0
- {qwak_sdk-0.1.0.dist-info → qwak_sdk-0.2.20rc0.dist-info}/WHEEL +1 -2
- qwak_sdk-0.2.20rc0.dist-info/entry_points.txt +3 -0
- qwak_sdk-0.1.0.dist-info/METADATA +0 -19
- qwak_sdk-0.1.0.dist-info/RECORD +0 -5
- qwak_sdk-0.1.0.dist-info/top_level.txt +0 -1
- {qwak-sdk → qwak_sdk/commands}/__init__.py +0 -0
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
from typing import List, Optional
|
|
2
|
+
|
|
3
|
+
from _qwak_proto.qwak.feature_store.features.feature_set_pb2 import Feature
|
|
4
|
+
from _qwak_proto.qwak.features_operator.v3.features_operator_pb2 import (
|
|
5
|
+
SparkColumnDescription,
|
|
6
|
+
ValidationSuccessResponse,
|
|
7
|
+
)
|
|
8
|
+
from qwak.clients.feature_store import FeatureRegistryClient
|
|
9
|
+
from qwak.clients.feature_store.operator_client import FeaturesOperatorClient
|
|
10
|
+
from qwak.exceptions import QwakException
|
|
11
|
+
from qwak.feature_store.data_sources.batch_sources._batch import BaseBatchSource
|
|
12
|
+
from qwak.feature_store.entities.entity import Entity
|
|
13
|
+
from qwak.feature_store.feature_sets.batch import BatchFeatureSetV1
|
|
14
|
+
from tabulate import tabulate
|
|
15
|
+
|
|
16
|
+
from qwak_sdk.inner.file_registry import extract_class_objects
|
|
17
|
+
from qwak_sdk.inner.tools.cli_tools import ask_yesno
|
|
18
|
+
from qwak_sdk.tools.utils import qwak_spinner
|
|
19
|
+
|
|
20
|
+
DELIMITER = "----------------------------------------"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _register_entities(
|
|
24
|
+
qwak_python_files: List[str], registry: FeatureRegistryClient, force: bool
|
|
25
|
+
):
|
|
26
|
+
"""
|
|
27
|
+
Register Feature Store Entity Objects
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
qwak_python_files: a list of python files containing qwak package imports
|
|
31
|
+
registry: FeatureRegistryClient
|
|
32
|
+
force: boolean determining if to force register all encountered Entity objects
|
|
33
|
+
"""
|
|
34
|
+
with qwak_spinner(begin_text="Finding Entities to register", print_callback=print):
|
|
35
|
+
qwak_entities: List[Entity] = extract_class_objects(qwak_python_files, Entity)
|
|
36
|
+
|
|
37
|
+
print(f"👀 Found {len(qwak_entities)} Entities")
|
|
38
|
+
for entity, source_file_path in qwak_entities:
|
|
39
|
+
existing_entity = registry.get_entity_by_name(entity.name)
|
|
40
|
+
if existing_entity:
|
|
41
|
+
if ask_yesno(
|
|
42
|
+
f"Update existing Entity '{entity.name}' from source file '{source_file_path}'?",
|
|
43
|
+
force,
|
|
44
|
+
):
|
|
45
|
+
registry.update_entity(
|
|
46
|
+
existing_entity.entity.entity_definition.entity_id,
|
|
47
|
+
entity.to_proto(),
|
|
48
|
+
)
|
|
49
|
+
else:
|
|
50
|
+
if ask_yesno(
|
|
51
|
+
f"Create new Entity '{entity.name}' from source file '{source_file_path}'?",
|
|
52
|
+
force,
|
|
53
|
+
):
|
|
54
|
+
registry.create_entity(entity.to_proto())
|
|
55
|
+
print(DELIMITER)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _register_data_sources(
|
|
59
|
+
qwak_python_files: List[str],
|
|
60
|
+
registry: FeatureRegistryClient,
|
|
61
|
+
operator_client: FeaturesOperatorClient,
|
|
62
|
+
force: bool,
|
|
63
|
+
no_validation: bool,
|
|
64
|
+
ignore_validation_errors: bool,
|
|
65
|
+
):
|
|
66
|
+
"""
|
|
67
|
+
Register Feature Store Data Source Objects
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
qwak_python_files: a list of python files containing qwak package imports
|
|
71
|
+
registry: FeatureRegistryClient
|
|
72
|
+
operator_client: features operator grpc client
|
|
73
|
+
force: boolean determining if to force register all encountered Data Source objects
|
|
74
|
+
no_validation: whether to validate entities
|
|
75
|
+
ignore_validation_errors: whether to ignore and continue registering objects after encountering validation errors
|
|
76
|
+
"""
|
|
77
|
+
with qwak_spinner(
|
|
78
|
+
begin_text="Finding Data Sources to register", print_callback=print
|
|
79
|
+
):
|
|
80
|
+
qwak_sources = extract_class_objects(qwak_python_files, BaseBatchSource)
|
|
81
|
+
|
|
82
|
+
print(f"👀 Found {len(qwak_sources)} Data Sources")
|
|
83
|
+
for data_source, source_file_path in qwak_sources:
|
|
84
|
+
validation_failed = False
|
|
85
|
+
|
|
86
|
+
if no_validation:
|
|
87
|
+
print("Skipping data source validation")
|
|
88
|
+
else:
|
|
89
|
+
try:
|
|
90
|
+
_handle_data_source_validation(operator_client, data_source)
|
|
91
|
+
except Exception as e:
|
|
92
|
+
print(str(e))
|
|
93
|
+
validation_failed = True
|
|
94
|
+
|
|
95
|
+
if validation_failed and not ignore_validation_errors:
|
|
96
|
+
print("Not continuing to registration due to failure in validation")
|
|
97
|
+
exit(1)
|
|
98
|
+
|
|
99
|
+
existing_source = registry.get_data_source_by_name(data_source.name)
|
|
100
|
+
if existing_source:
|
|
101
|
+
if ask_yesno(
|
|
102
|
+
f"Update existing Data Source '{data_source.name}' from source file '{source_file_path}'?",
|
|
103
|
+
force,
|
|
104
|
+
):
|
|
105
|
+
registry.update_data_source(
|
|
106
|
+
existing_source.data_source.data_source_definition.data_source_id,
|
|
107
|
+
data_source._to_proto(),
|
|
108
|
+
)
|
|
109
|
+
else:
|
|
110
|
+
if ask_yesno(
|
|
111
|
+
f"Create Data Source '{data_source.name}' from source file '{source_file_path}'?",
|
|
112
|
+
force,
|
|
113
|
+
):
|
|
114
|
+
registry.create_data_source(data_source._to_proto())
|
|
115
|
+
print(DELIMITER)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _handle_data_source_validation(
|
|
119
|
+
operator_client: FeaturesOperatorClient,
|
|
120
|
+
data_source: BaseBatchSource,
|
|
121
|
+
):
|
|
122
|
+
print(f"Validating '{data_source.name}' data source")
|
|
123
|
+
with qwak_spinner(begin_text="", print_callback=print):
|
|
124
|
+
result = operator_client.validate_data_source_blocking(
|
|
125
|
+
data_source_spec=data_source._to_proto(), num_samples=10
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
response = getattr(result, result.WhichOneof("type"))
|
|
129
|
+
if isinstance(response, ValidationSuccessResponse):
|
|
130
|
+
print("✅ Validation completed successfully, got data source columns:")
|
|
131
|
+
|
|
132
|
+
table = [
|
|
133
|
+
(x.column_name, x.spark_type) for x in response.spark_column_description
|
|
134
|
+
]
|
|
135
|
+
print(tabulate(table, headers=["column name", "type"]))
|
|
136
|
+
else:
|
|
137
|
+
raise QwakException(f"🧨 Validation failed:\n{response}")
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def _register_features_sets(
|
|
141
|
+
qwak_python_files: List[str],
|
|
142
|
+
registry: FeatureRegistryClient,
|
|
143
|
+
operator_client: FeaturesOperatorClient,
|
|
144
|
+
force: bool,
|
|
145
|
+
git_commit: str,
|
|
146
|
+
no_validation: bool,
|
|
147
|
+
ignore_validation_errors: bool,
|
|
148
|
+
):
|
|
149
|
+
"""
|
|
150
|
+
Register Feature Store Feature Set Objects
|
|
151
|
+
|
|
152
|
+
Args:
|
|
153
|
+
qwak_python_files: a list of python files containing qwak package imports
|
|
154
|
+
registry: FeatureRegistryClient
|
|
155
|
+
operator_client: features operator grpc client
|
|
156
|
+
force: boolean determining if to force register all encountered Feature Set objects
|
|
157
|
+
git_commit: the git commit of the parent folder
|
|
158
|
+
no_validation: whether to validate entities
|
|
159
|
+
ignore_validation_errors: whether to ignore and continue registering objects after encountering validation errors
|
|
160
|
+
"""
|
|
161
|
+
with qwak_spinner(
|
|
162
|
+
begin_text="Finding Feature Sets to register", print_callback=print
|
|
163
|
+
):
|
|
164
|
+
qwak_feature_sets = extract_class_objects(qwak_python_files, BatchFeatureSetV1)
|
|
165
|
+
|
|
166
|
+
print(f"👀 Found {len(qwak_feature_sets)} Feature Set(s)")
|
|
167
|
+
|
|
168
|
+
for feature_set, source_file_path in qwak_feature_sets:
|
|
169
|
+
existing_feature_set = registry.get_feature_set_by_name(feature_set.name)
|
|
170
|
+
|
|
171
|
+
registration: bool = False
|
|
172
|
+
if existing_feature_set:
|
|
173
|
+
registration = ask_yesno(
|
|
174
|
+
f"Update existing feature set '{feature_set.name}' from source file '{source_file_path}'?", # nosec B608
|
|
175
|
+
force,
|
|
176
|
+
)
|
|
177
|
+
else:
|
|
178
|
+
registration = ask_yesno(
|
|
179
|
+
f"Create new feature set '{feature_set.name}' from source file '{source_file_path}'?",
|
|
180
|
+
force,
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
if registration:
|
|
184
|
+
spark_columns_features = _batch_v1_feature_set_validation(
|
|
185
|
+
feature_set=feature_set,
|
|
186
|
+
no_validation=no_validation,
|
|
187
|
+
operator=operator_client,
|
|
188
|
+
registry=registry,
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
proto_feature_set = feature_set._to_proto(
|
|
192
|
+
git_commit, spark_columns_features, registry
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
if existing_feature_set:
|
|
196
|
+
registry.update_feature_set(
|
|
197
|
+
existing_feature_set.feature_set.feature_set_definition.feature_set_id,
|
|
198
|
+
proto_feature_set,
|
|
199
|
+
)
|
|
200
|
+
else:
|
|
201
|
+
registry.create_feature_set(proto_feature_set)
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def _handle_batch_v1_feature_set_validation(
|
|
205
|
+
operator_client: FeaturesOperatorClient,
|
|
206
|
+
registry_client: FeatureRegistryClient,
|
|
207
|
+
feature_set: BatchFeatureSetV1,
|
|
208
|
+
) -> List[SparkColumnDescription]:
|
|
209
|
+
print(f"Validating '{feature_set.name}' feature set")
|
|
210
|
+
with qwak_spinner(begin_text="", print_callback=print):
|
|
211
|
+
feature_set_spec = feature_set._to_proto(
|
|
212
|
+
feature_registry=registry_client, features=None, git_commit=None
|
|
213
|
+
)
|
|
214
|
+
result = operator_client.validate_featureset_blocking(
|
|
215
|
+
feature_set_spec, resource_path=None, num_samples=10
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
response = getattr(result, result.WhichOneof("type"))
|
|
219
|
+
if isinstance(response, ValidationSuccessResponse):
|
|
220
|
+
print("✅ Validation completed successfully, got data source columns:")
|
|
221
|
+
table = [
|
|
222
|
+
(x.column_name, x.spark_type) for x in response.spark_column_description
|
|
223
|
+
]
|
|
224
|
+
print(tabulate(table, headers=["column name", "type"]))
|
|
225
|
+
return response.spark_column_description
|
|
226
|
+
|
|
227
|
+
else:
|
|
228
|
+
raise QwakException(f"🧨 Validation failed:\n{response}")
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def _get_features_from_spark_columns_description(
|
|
232
|
+
spark_columns_description: List[SparkColumnDescription],
|
|
233
|
+
) -> Optional[List[Feature]]:
|
|
234
|
+
if spark_columns_description:
|
|
235
|
+
spark_features = []
|
|
236
|
+
for spark_column in spark_columns_description:
|
|
237
|
+
feature_col_name_list = str(spark_column.column_name).split(".")
|
|
238
|
+
feature_name = (
|
|
239
|
+
feature_col_name_list[1]
|
|
240
|
+
if feature_col_name_list.__len__() == 2
|
|
241
|
+
else spark_column.column_name
|
|
242
|
+
)
|
|
243
|
+
spark_features.append(
|
|
244
|
+
Feature(
|
|
245
|
+
feature_name=feature_name,
|
|
246
|
+
feature_type=spark_column.spark_type,
|
|
247
|
+
)
|
|
248
|
+
)
|
|
249
|
+
return spark_features
|
|
250
|
+
else:
|
|
251
|
+
return None
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
def _batch_v1_feature_set_validation(
|
|
255
|
+
feature_set: BatchFeatureSetV1,
|
|
256
|
+
no_validation: bool,
|
|
257
|
+
operator: FeaturesOperatorClient,
|
|
258
|
+
registry: FeatureRegistryClient,
|
|
259
|
+
) -> Optional[List[Feature]]:
|
|
260
|
+
"""
|
|
261
|
+
Validates featureset transformation
|
|
262
|
+
Args:
|
|
263
|
+
artifact_path: uploaded artifact zip path
|
|
264
|
+
feature_set: BatchFeatureSetV1 featureset
|
|
265
|
+
no_validation: skip validation
|
|
266
|
+
operator: Operator client
|
|
267
|
+
registry: Registry client
|
|
268
|
+
Returns:
|
|
269
|
+
Optional list of features returned from validation
|
|
270
|
+
"""
|
|
271
|
+
spark_columns_features: Optional[List[Feature]] = []
|
|
272
|
+
|
|
273
|
+
if not no_validation:
|
|
274
|
+
try:
|
|
275
|
+
spark_columns_description = _handle_batch_v1_feature_set_validation(
|
|
276
|
+
operator_client=operator,
|
|
277
|
+
registry_client=registry,
|
|
278
|
+
feature_set=feature_set,
|
|
279
|
+
)
|
|
280
|
+
spark_columns_features = _get_features_from_spark_columns_description(
|
|
281
|
+
spark_columns_description
|
|
282
|
+
)
|
|
283
|
+
except Exception as e:
|
|
284
|
+
print(str(e))
|
|
285
|
+
print("Not continuing to registration due to failure in validation")
|
|
286
|
+
exit(1)
|
|
287
|
+
else:
|
|
288
|
+
print(f"Skipping validation for '{feature_set.name}' feature set")
|
|
289
|
+
return spark_columns_features
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
import click
|
|
5
|
+
from qwak.clients.feature_store import FeatureRegistryClient
|
|
6
|
+
from qwak.clients.feature_store.operator_client import FeaturesOperatorClient
|
|
7
|
+
|
|
8
|
+
from qwak_sdk.commands.feature_store.register._logic import (
|
|
9
|
+
_register_data_sources,
|
|
10
|
+
_register_entities,
|
|
11
|
+
_register_features_sets,
|
|
12
|
+
)
|
|
13
|
+
from qwak_sdk.inner.file_registry import list_qwak_python_files
|
|
14
|
+
from qwak_sdk.inner.tools.cli_tools import QwakCommand
|
|
15
|
+
from qwak_sdk.tools.utils import qwak_spinner
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@click.command(
|
|
19
|
+
"register",
|
|
20
|
+
cls=QwakCommand,
|
|
21
|
+
help="Register and deploy all feature store object under the given path. Registered "
|
|
22
|
+
"features will be visible on the Qwak management platform after registration",
|
|
23
|
+
)
|
|
24
|
+
@click.option(
|
|
25
|
+
"--path",
|
|
26
|
+
"-p",
|
|
27
|
+
type=click.Path(exists=True),
|
|
28
|
+
metavar="PATH",
|
|
29
|
+
help="Directory / module where qwak feature store objects are stored",
|
|
30
|
+
)
|
|
31
|
+
@click.option(
|
|
32
|
+
"--force",
|
|
33
|
+
"-f",
|
|
34
|
+
default=False,
|
|
35
|
+
is_flag=True,
|
|
36
|
+
metavar="FLAG",
|
|
37
|
+
help="Force register all found qwak Feature Store objects",
|
|
38
|
+
)
|
|
39
|
+
@click.option(
|
|
40
|
+
"--no-validation",
|
|
41
|
+
"-nv",
|
|
42
|
+
default=False,
|
|
43
|
+
is_flag=True,
|
|
44
|
+
metavar="FLAG",
|
|
45
|
+
help="Skip validation for all found qwak Feature Store objects",
|
|
46
|
+
)
|
|
47
|
+
@click.option(
|
|
48
|
+
"--ignore-validation-errors",
|
|
49
|
+
"-ive",
|
|
50
|
+
default=False,
|
|
51
|
+
is_flag=True,
|
|
52
|
+
metavar="FLAG",
|
|
53
|
+
help="Ignore validation errors. Continue registering even if an error occurs",
|
|
54
|
+
)
|
|
55
|
+
def register_fs_objects(
|
|
56
|
+
path: Path,
|
|
57
|
+
force: bool,
|
|
58
|
+
no_validation: bool,
|
|
59
|
+
ignore_validation_errors: bool,
|
|
60
|
+
**kwargs,
|
|
61
|
+
):
|
|
62
|
+
if not path:
|
|
63
|
+
path = Path.cwd()
|
|
64
|
+
else:
|
|
65
|
+
path = Path(path)
|
|
66
|
+
|
|
67
|
+
if path.is_file():
|
|
68
|
+
qwak_python_files = [(str(path), os.path.abspath(path))]
|
|
69
|
+
elif Path.is_dir(path):
|
|
70
|
+
with qwak_spinner(
|
|
71
|
+
begin_text="Recursively looking for python files in input dir",
|
|
72
|
+
print_callback=print,
|
|
73
|
+
) as sp:
|
|
74
|
+
qwak_python_files = list_qwak_python_files(path, sp)
|
|
75
|
+
|
|
76
|
+
try:
|
|
77
|
+
import git
|
|
78
|
+
|
|
79
|
+
git_commit = git.Repo(path, search_parent_directories=True).head.commit.hexsha
|
|
80
|
+
except Exception:
|
|
81
|
+
# be super defensive on Git errors. Failing to fetch anything git related should not fail the registration
|
|
82
|
+
git_commit = None
|
|
83
|
+
|
|
84
|
+
registry_client = FeatureRegistryClient()
|
|
85
|
+
operator_client = FeaturesOperatorClient()
|
|
86
|
+
_register_entities(qwak_python_files, registry_client, force)
|
|
87
|
+
|
|
88
|
+
_register_data_sources(
|
|
89
|
+
qwak_python_files,
|
|
90
|
+
registry_client,
|
|
91
|
+
operator_client,
|
|
92
|
+
force,
|
|
93
|
+
no_validation,
|
|
94
|
+
ignore_validation_errors,
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
_register_features_sets(
|
|
98
|
+
qwak_python_files,
|
|
99
|
+
registry_client,
|
|
100
|
+
operator_client,
|
|
101
|
+
force,
|
|
102
|
+
git_commit,
|
|
103
|
+
no_validation,
|
|
104
|
+
ignore_validation_errors,
|
|
105
|
+
)
|
|
File without changes
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import click
|
|
2
|
+
from qwak.clients.feature_store import FeatureRegistryClient
|
|
3
|
+
from qwak.exceptions import QwakException
|
|
4
|
+
|
|
5
|
+
from qwak_sdk.inner.tools.cli_tools import QwakCommand
|
|
6
|
+
from qwak_sdk.tools.colors import Color
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@click.command("resume", cls=QwakCommand, help="Resume a paused feature set")
|
|
10
|
+
@click.argument("name")
|
|
11
|
+
def resume_feature_set(name, **kwargs):
|
|
12
|
+
try:
|
|
13
|
+
FeatureRegistryClient().resume_feature_set(feature_set_name=name)
|
|
14
|
+
except Exception as e:
|
|
15
|
+
print(f"{Color.RED} Failed to resume feature set {name} {Color.END}")
|
|
16
|
+
raise QwakException(f"Failed to resume feature set {name}") from e
|
|
17
|
+
|
|
18
|
+
print(f"{Color.GREEN}Successfully resume feature set {Color.YELLOW}{name}")
|
|
File without changes
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import click
|
|
2
|
+
from qwak.clients.feature_store import FeatureRegistryClient
|
|
3
|
+
from qwak.exceptions import QwakException
|
|
4
|
+
|
|
5
|
+
from qwak_sdk.inner.tools.cli_tools import QwakCommand
|
|
6
|
+
from qwak_sdk.tools.colors import Color
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@click.command(
|
|
10
|
+
"trigger", cls=QwakCommand, help="Trigger a batch feature set job ingestion job"
|
|
11
|
+
)
|
|
12
|
+
@click.argument("name")
|
|
13
|
+
def trigger_feature_set(name, **kwargs):
|
|
14
|
+
"""
|
|
15
|
+
Trigger a batch feature set ingestion job
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
name: feature set name that will be triggered
|
|
19
|
+
"""
|
|
20
|
+
try:
|
|
21
|
+
FeatureRegistryClient().run_feature_set(feature_set_name=name)
|
|
22
|
+
except Exception as e:
|
|
23
|
+
print(
|
|
24
|
+
f"{Color.RED} Failed to trigger a batch feature set ingestion for feature set {name} {Color.END}"
|
|
25
|
+
)
|
|
26
|
+
raise QwakException(
|
|
27
|
+
f"Failed to trigger a batch feature set ingestion for feature set {name}"
|
|
28
|
+
) from e
|
|
29
|
+
|
|
30
|
+
print(
|
|
31
|
+
f"{Color.GREEN}Successfully triggered a batch feature set ingestion for feature set {Color.YELLOW}{name}"
|
|
32
|
+
)
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import List
|
|
4
|
+
|
|
5
|
+
from _qwak_proto.qwak.deployment.deployment_pb2 import TrafficSpec, Variation
|
|
6
|
+
from qwak.exceptions import QwakException
|
|
7
|
+
|
|
8
|
+
from qwak_sdk.commands.models.deployments.deploy._logic.deploy_config import (
|
|
9
|
+
DeployConfig,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def validate_percentages(variations: List[Variation]):
|
|
14
|
+
for variation in variations:
|
|
15
|
+
if not (0 <= variation.traffic.percentage <= 100):
|
|
16
|
+
raise QwakException(
|
|
17
|
+
f"The variation '{variation.name}' contains invalid value '{variation.traffic.percentage}'. "
|
|
18
|
+
f"Value must be between 0 and 100."
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
non_shadow_variations = list(filter(lambda v: not v.traffic.is_shadow, variations))
|
|
22
|
+
non_shadow_variations_percentage_sum = sum(
|
|
23
|
+
map(lambda v: v.traffic.percentage, non_shadow_variations)
|
|
24
|
+
)
|
|
25
|
+
if non_shadow_variations and non_shadow_variations_percentage_sum != 100:
|
|
26
|
+
raise QwakException(
|
|
27
|
+
"The variations do not sum to 100 percent. Please go over the variations config file."
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def validate_shadow_variation(variations: List[Variation]):
|
|
32
|
+
shadow_variations = list(filter(lambda v: v.traffic.is_shadow, variations))
|
|
33
|
+
if len(shadow_variations) > 1:
|
|
34
|
+
shadow_variations_names = list(map(lambda v: v.name, shadow_variations))
|
|
35
|
+
raise QwakException(
|
|
36
|
+
f"The variations contain more than one shadow variation {shadow_variations_names}. "
|
|
37
|
+
f"Please go over the variations config file."
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def create_variation_from_variation_config(
|
|
42
|
+
variation_def: DeployConfig.Realtime.VariationConfig,
|
|
43
|
+
) -> Variation:
|
|
44
|
+
try:
|
|
45
|
+
return Variation(
|
|
46
|
+
name=variation_def.name,
|
|
47
|
+
traffic=TrafficSpec(
|
|
48
|
+
percentage=variation_def.traffic.percentage,
|
|
49
|
+
is_shadow=variation_def.traffic.shadow,
|
|
50
|
+
),
|
|
51
|
+
)
|
|
52
|
+
except Exception:
|
|
53
|
+
raise QwakException(
|
|
54
|
+
f"Could not parse variation {variation_def}. Please check you variation configuration file."
|
|
55
|
+
)
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
from typing import List
|
|
2
|
+
|
|
3
|
+
from .config.config_v1 import ConfigV1
|
|
4
|
+
from .constant.step_description import BuildPhase, PhaseDetails
|
|
5
|
+
from .context import Context
|
|
6
|
+
from .interface.step_inteface import Step
|
|
7
|
+
from .phase.a_fetch_model_code import get_fetch_model_code_steps
|
|
8
|
+
from .phase.b_remote_register_qwak_build import get_remote_register_qwak_build_steps
|
|
9
|
+
from .phase.c_deploy import get_deploy_stepss
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class StepsPipeline:
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
config: ConfigV1,
|
|
16
|
+
context: Context = None,
|
|
17
|
+
build_phase: BuildPhase = None,
|
|
18
|
+
) -> None:
|
|
19
|
+
self._phases: List[StepsPipeline] = []
|
|
20
|
+
self._steps: List[Step] = []
|
|
21
|
+
if not context:
|
|
22
|
+
self.context = Context()
|
|
23
|
+
self._config = config
|
|
24
|
+
self.build_phase = build_phase
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
def phases(self) -> List["StepsPipeline"]:
|
|
28
|
+
return self._phases
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def steps(self) -> List[Step]:
|
|
32
|
+
return self._steps
|
|
33
|
+
|
|
34
|
+
def add_phase(self, steps: List[Step], build_phase: BuildPhase):
|
|
35
|
+
phase = StepsPipeline(
|
|
36
|
+
config=self._config, context=self.context, build_phase=build_phase
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
for step in steps:
|
|
40
|
+
step.context = self.context
|
|
41
|
+
step.config = self._config
|
|
42
|
+
step.build_phase = build_phase
|
|
43
|
+
phase._steps.append(step)
|
|
44
|
+
|
|
45
|
+
self._phases.append(phase)
|
|
46
|
+
|
|
47
|
+
def get_phase_details(self) -> PhaseDetails:
|
|
48
|
+
return PhaseDetails(self.build_phase)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def remote_build_steps(config: ConfigV1) -> StepsPipeline:
|
|
52
|
+
steps_root = StepsPipeline(config=config)
|
|
53
|
+
steps_root.add_phase(
|
|
54
|
+
steps=get_fetch_model_code_steps(),
|
|
55
|
+
build_phase=BuildPhase.FETCHING_MODEL_CODE,
|
|
56
|
+
)
|
|
57
|
+
steps_root.add_phase(
|
|
58
|
+
steps=get_remote_register_qwak_build_steps(),
|
|
59
|
+
build_phase=BuildPhase.REGISTERING_QWAK_BUILD,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
if config.deploy:
|
|
63
|
+
steps_root.add_phase(
|
|
64
|
+
steps=get_deploy_stepss(),
|
|
65
|
+
build_phase=BuildPhase.DEPLOY_PHASE,
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
return steps_root
|
|
File without changes
|