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,367 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from typing import List, Optional, Tuple, cast
|
|
3
|
+
|
|
4
|
+
from _qwak_proto.qwak.feature_store.entities.entity_pb2 import (
|
|
5
|
+
EntityDefinition as ProtoEntityDefinition,
|
|
6
|
+
)
|
|
7
|
+
from _qwak_proto.qwak.feature_store.features.feature_set_pb2 import (
|
|
8
|
+
Feature as ProtoFeature,
|
|
9
|
+
)
|
|
10
|
+
from _qwak_proto.qwak.feature_store.features.feature_set_service_pb2 import (
|
|
11
|
+
GetFeatureSetByNameResponse as ProtoGetFeatureSetByNameResponse,
|
|
12
|
+
)
|
|
13
|
+
from qwak.clients.feature_store import FeatureRegistryClient
|
|
14
|
+
from qwak.exceptions import QwakException
|
|
15
|
+
from qwak.feature_store.data_sources.base import BaseSource
|
|
16
|
+
from qwak.feature_store.entities.entity import Entity
|
|
17
|
+
from qwak.feature_store.feature_sets.base_feature_set import BaseFeatureSet
|
|
18
|
+
from qwak.feature_store.validations.validation_options import (
|
|
19
|
+
FeatureSetValidationOptions,
|
|
20
|
+
)
|
|
21
|
+
from qwak.feature_store.validations.validation_response import (
|
|
22
|
+
SuccessValidationResponse,
|
|
23
|
+
ValidationResponse,
|
|
24
|
+
)
|
|
25
|
+
from tabulate import tabulate
|
|
26
|
+
|
|
27
|
+
from qwak_sdk.inner.file_registry import extract_class_objects
|
|
28
|
+
from qwak_sdk.inner.tools.cli_tools import ask_yesno
|
|
29
|
+
from qwak_sdk.tools.utils import qwak_spinner
|
|
30
|
+
|
|
31
|
+
DELIMITER = "----------------------------------------"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _register_entities(
|
|
35
|
+
qwak_python_files: List[Tuple[str, str]],
|
|
36
|
+
registry: FeatureRegistryClient,
|
|
37
|
+
force: bool,
|
|
38
|
+
):
|
|
39
|
+
"""
|
|
40
|
+
Register Feature Store Entity Objects
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
qwak_python_files: a list of python files containing qwak package imports
|
|
44
|
+
registry: FeatureRegistryClient
|
|
45
|
+
force: boolean determining if to force register all encountered Entity objects
|
|
46
|
+
"""
|
|
47
|
+
with qwak_spinner(begin_text="Finding Entities to register", print_callback=print):
|
|
48
|
+
qwak_entities: List[Tuple[Entity, str]] = extract_class_objects(
|
|
49
|
+
qwak_python_files, Entity
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
print(f"👀 Found {len(qwak_entities)} Entities")
|
|
53
|
+
for entity, source_file_path in qwak_entities:
|
|
54
|
+
existing_entity = registry.get_entity_by_name(entity.name)
|
|
55
|
+
if existing_entity:
|
|
56
|
+
if ask_yesno(
|
|
57
|
+
f"Update existing Entity '{entity.name}' from source file '{source_file_path}'?",
|
|
58
|
+
force,
|
|
59
|
+
):
|
|
60
|
+
registry.update_entity(
|
|
61
|
+
existing_entity.entity.entity_definition.entity_id,
|
|
62
|
+
entity._to_proto(),
|
|
63
|
+
)
|
|
64
|
+
else:
|
|
65
|
+
if ask_yesno(
|
|
66
|
+
f"Create new Entity '{entity.name}' from source file '{source_file_path}'?",
|
|
67
|
+
force,
|
|
68
|
+
):
|
|
69
|
+
registry.create_entity(entity._to_proto())
|
|
70
|
+
print(DELIMITER)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _register_data_sources(
|
|
74
|
+
qwak_python_files: List[Tuple[str, str]],
|
|
75
|
+
registry: FeatureRegistryClient,
|
|
76
|
+
force: bool,
|
|
77
|
+
no_validation: bool,
|
|
78
|
+
ignore_validation_errors: bool,
|
|
79
|
+
):
|
|
80
|
+
"""
|
|
81
|
+
Register Feature Store Data Source Objects
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
qwak_python_files: a list of python files containing qwak package imports
|
|
85
|
+
registry: FeatureRegistryClient
|
|
86
|
+
force: boolean determining if to force register all encountered Data Source objects
|
|
87
|
+
no_validation: whether to validate entities
|
|
88
|
+
ignore_validation_errors: whether to ignore and continue registering objects after encountering validation errors
|
|
89
|
+
"""
|
|
90
|
+
with qwak_spinner(
|
|
91
|
+
begin_text="Finding Data Sources to register", print_callback=print
|
|
92
|
+
):
|
|
93
|
+
qwak_sources: List[Tuple[BaseSource, str]] = extract_class_objects(
|
|
94
|
+
qwak_python_files, BaseSource
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
print(f"👀 Found {len(qwak_sources)} Data Sources")
|
|
98
|
+
for data_source, source_file_path in qwak_sources:
|
|
99
|
+
validation_failed = False
|
|
100
|
+
artifact_url: Optional[str] = None
|
|
101
|
+
|
|
102
|
+
if no_validation:
|
|
103
|
+
print("Skipping data source validation")
|
|
104
|
+
else:
|
|
105
|
+
try:
|
|
106
|
+
artifact_url = _handle_data_source_validation(data_source)
|
|
107
|
+
except Exception as e:
|
|
108
|
+
print(str(e))
|
|
109
|
+
validation_failed = True
|
|
110
|
+
|
|
111
|
+
if validation_failed and not ignore_validation_errors:
|
|
112
|
+
print("Not continuing to registration due to failure in validation")
|
|
113
|
+
exit(1)
|
|
114
|
+
|
|
115
|
+
existing_source = registry.get_data_source_by_name(data_source.name)
|
|
116
|
+
if existing_source:
|
|
117
|
+
if ask_yesno(
|
|
118
|
+
f"Update existing Data Source '{data_source.name}' from source file '{source_file_path}'?",
|
|
119
|
+
force,
|
|
120
|
+
):
|
|
121
|
+
data_source_proto, _ = data_source._prepare_and_get(
|
|
122
|
+
artifact_url=artifact_url,
|
|
123
|
+
source_definition_path=Path(source_file_path),
|
|
124
|
+
)
|
|
125
|
+
registry.update_data_source(
|
|
126
|
+
existing_source.data_source.data_source_definition.data_source_id,
|
|
127
|
+
data_source_proto,
|
|
128
|
+
)
|
|
129
|
+
else:
|
|
130
|
+
if ask_yesno(
|
|
131
|
+
f"Create Data Source '{data_source.name}' from source file '{source_file_path}'?",
|
|
132
|
+
force,
|
|
133
|
+
):
|
|
134
|
+
data_source_proto, _ = data_source._prepare_and_get(
|
|
135
|
+
artifact_url=artifact_url,
|
|
136
|
+
source_definition_path=Path(source_file_path),
|
|
137
|
+
)
|
|
138
|
+
registry.create_data_source(data_source_proto)
|
|
139
|
+
print(DELIMITER)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def _handle_data_source_validation(
|
|
143
|
+
data_source: BaseSource,
|
|
144
|
+
) -> Optional[str]:
|
|
145
|
+
print(f"Validating '{data_source.name}' data source")
|
|
146
|
+
with qwak_spinner(begin_text="", print_callback=print):
|
|
147
|
+
from qwak.feature_store.validations.validator import FeaturesOperatorValidator
|
|
148
|
+
|
|
149
|
+
v = FeaturesOperatorValidator()
|
|
150
|
+
response: ValidationResponse
|
|
151
|
+
artifact_url: Optional[str]
|
|
152
|
+
|
|
153
|
+
response, artifact_url = v.validate_data_source(data_source=data_source)
|
|
154
|
+
if isinstance(response, SuccessValidationResponse):
|
|
155
|
+
print_validation_outputs(response.stdout, response.stderr)
|
|
156
|
+
print("✅ Validation completed successfully, got data source columns:")
|
|
157
|
+
|
|
158
|
+
table = [(x.feature_name, x.feature_type) for x in response.features]
|
|
159
|
+
print(tabulate(table, headers=["column name", "type"]))
|
|
160
|
+
|
|
161
|
+
return artifact_url
|
|
162
|
+
else:
|
|
163
|
+
raise QwakException(f"🧨 Validation failed: \n{response}")
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def _register_features_sets(
|
|
167
|
+
qwak_python_files: List[Tuple[str, str]],
|
|
168
|
+
registry: FeatureRegistryClient,
|
|
169
|
+
force: bool,
|
|
170
|
+
git_commit: str,
|
|
171
|
+
no_validation: bool,
|
|
172
|
+
ignore_validation_errors: bool,
|
|
173
|
+
data_source_limit: Optional[int] = None,
|
|
174
|
+
):
|
|
175
|
+
"""
|
|
176
|
+
Register Feature Store Feature Set Objects
|
|
177
|
+
|
|
178
|
+
Args:
|
|
179
|
+
qwak_python_files: a list of python files containing qwak package imports
|
|
180
|
+
registry: FeatureRegistryClient
|
|
181
|
+
force: boolean determining if to force register all encountered Feature Set objects
|
|
182
|
+
git_commit: the git commit of the parent folder
|
|
183
|
+
no_validation: whether to validate entities
|
|
184
|
+
ignore_validation_errors: whether to ignore and continue registering objects after encountering validation errors
|
|
185
|
+
"""
|
|
186
|
+
with qwak_spinner(
|
|
187
|
+
begin_text="Finding Feature Sets to register", print_callback=print
|
|
188
|
+
):
|
|
189
|
+
qwak_feature_sets = extract_class_objects(qwak_python_files, BaseFeatureSet)
|
|
190
|
+
|
|
191
|
+
print(f"👀 Found {len(qwak_feature_sets)} Feature Set(s)")
|
|
192
|
+
|
|
193
|
+
for featureset, source_file_path in qwak_feature_sets:
|
|
194
|
+
featureset = cast(BaseFeatureSet, featureset)
|
|
195
|
+
existing_feature_set: ProtoGetFeatureSetByNameResponse = (
|
|
196
|
+
registry.get_feature_set_by_name(featureset.name)
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
registration: bool = False
|
|
200
|
+
if existing_feature_set:
|
|
201
|
+
# Provide entity information of registered feature set before any other operation
|
|
202
|
+
if featureset.key:
|
|
203
|
+
featureset.entity = (
|
|
204
|
+
existing_feature_set.feature_set.feature_set_definition.feature_set_spec.entity.entity_spec.name
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
registration = ask_yesno(
|
|
208
|
+
f"Update existing feature set '{featureset.name}' from source file '{source_file_path}'?", # nosec B608
|
|
209
|
+
force,
|
|
210
|
+
)
|
|
211
|
+
else:
|
|
212
|
+
registration = ask_yesno(
|
|
213
|
+
f"Create new feature set '{featureset.name}' from source file '{source_file_path}'?",
|
|
214
|
+
force,
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
if registration:
|
|
218
|
+
features: Optional[List[ProtoFeature]] = []
|
|
219
|
+
artifact_url: Optional[str] = None
|
|
220
|
+
|
|
221
|
+
features, artifact_url = _validate_featureset(
|
|
222
|
+
featureset=featureset,
|
|
223
|
+
no_validation=no_validation,
|
|
224
|
+
ignore_validation_errors=ignore_validation_errors,
|
|
225
|
+
data_source_limit=data_source_limit,
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
proto_feature_set, _ = featureset._to_proto(
|
|
229
|
+
git_commit=git_commit,
|
|
230
|
+
features=features,
|
|
231
|
+
feature_registry=registry,
|
|
232
|
+
artifact_url=artifact_url,
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
if existing_feature_set:
|
|
236
|
+
registry.update_feature_set(
|
|
237
|
+
existing_feature_set.feature_set.feature_set_definition.feature_set_id,
|
|
238
|
+
proto_feature_set,
|
|
239
|
+
)
|
|
240
|
+
else:
|
|
241
|
+
_register_new_feature_set(
|
|
242
|
+
new_feature_set=featureset,
|
|
243
|
+
entity_key=proto_feature_set.entity,
|
|
244
|
+
registry=registry,
|
|
245
|
+
git_commit=git_commit,
|
|
246
|
+
features=features,
|
|
247
|
+
artifact_url=artifact_url,
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
def _register_new_feature_set(
|
|
252
|
+
new_feature_set: BaseFeatureSet,
|
|
253
|
+
entity_key: ProtoEntityDefinition,
|
|
254
|
+
registry: FeatureRegistryClient,
|
|
255
|
+
git_commit: str,
|
|
256
|
+
features: Optional[List[ProtoFeature]],
|
|
257
|
+
artifact_url: Optional[str] = None,
|
|
258
|
+
):
|
|
259
|
+
# Create entity for the defined key and set it as the fs's entity
|
|
260
|
+
if new_feature_set.key:
|
|
261
|
+
new_entity: Entity = Entity._from_proto(proto=entity_key)
|
|
262
|
+
try:
|
|
263
|
+
new_entity.register()
|
|
264
|
+
except QwakException:
|
|
265
|
+
raise QwakException(
|
|
266
|
+
f"Failed to create key for {new_feature_set.name}, "
|
|
267
|
+
f"aborting feature set creation"
|
|
268
|
+
)
|
|
269
|
+
new_feature_set.entity = new_entity.name
|
|
270
|
+
|
|
271
|
+
# this is done to retrieve the entities metadata
|
|
272
|
+
proto_feature_set, _ = new_feature_set._to_proto(
|
|
273
|
+
git_commit, features, registry, artifact_url=artifact_url
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
try:
|
|
277
|
+
registry.create_feature_set(proto_feature_set)
|
|
278
|
+
# rollback entity creation in case fs registration failed
|
|
279
|
+
except QwakException as e1:
|
|
280
|
+
try:
|
|
281
|
+
if new_feature_set.key:
|
|
282
|
+
registry.delete_entity(entity_id=proto_feature_set.entity.entity_id)
|
|
283
|
+
except QwakException:
|
|
284
|
+
raise e1
|
|
285
|
+
raise e1
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
def _handle_featureset_validation(
|
|
289
|
+
featureset: BaseFeatureSet,
|
|
290
|
+
data_source_limit: Optional[int] = None,
|
|
291
|
+
) -> Tuple[List[ProtoFeature], Optional[str]]:
|
|
292
|
+
print(f"Validating '{featureset.name}' feature set")
|
|
293
|
+
with qwak_spinner(begin_text="", print_callback=print):
|
|
294
|
+
from qwak.feature_store.validations.validator import FeaturesOperatorValidator
|
|
295
|
+
|
|
296
|
+
v = FeaturesOperatorValidator()
|
|
297
|
+
response: ValidationResponse
|
|
298
|
+
artifact_url: Optional[str]
|
|
299
|
+
validation_options = FeatureSetValidationOptions(
|
|
300
|
+
data_source_limit=data_source_limit
|
|
301
|
+
)
|
|
302
|
+
|
|
303
|
+
response, artifact_url = v.validate_featureset(
|
|
304
|
+
featureset=featureset, validation_options=validation_options
|
|
305
|
+
)
|
|
306
|
+
if isinstance(response, SuccessValidationResponse):
|
|
307
|
+
print_validation_outputs(response.stdout, response.stderr)
|
|
308
|
+
print("✅ Validation completed successfully, got data source columns:")
|
|
309
|
+
table = [(x.feature_name, x.feature_type) for x in response.features]
|
|
310
|
+
print(tabulate(table, headers=["column name", "type"]))
|
|
311
|
+
return response.features, artifact_url
|
|
312
|
+
else:
|
|
313
|
+
raise QwakException(f"🧨 Validation failed: \n{response}")
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
def _validate_featureset(
|
|
317
|
+
featureset: BaseFeatureSet,
|
|
318
|
+
no_validation: bool,
|
|
319
|
+
ignore_validation_errors: bool,
|
|
320
|
+
data_source_limit: Optional[int] = None,
|
|
321
|
+
) -> Tuple[List[ProtoFeature], Optional[str]]:
|
|
322
|
+
"""
|
|
323
|
+
Validates featureset transformation
|
|
324
|
+
Args:
|
|
325
|
+
featureset: BaseFeatureSet featureset
|
|
326
|
+
no_validation: skip validation
|
|
327
|
+
operator: Operator client
|
|
328
|
+
registry: Registry client
|
|
329
|
+
Returns:
|
|
330
|
+
Optional list of features returned from validation
|
|
331
|
+
"""
|
|
332
|
+
features: List[ProtoFeature] = []
|
|
333
|
+
artifact_url: Optional[str] = None
|
|
334
|
+
if not no_validation:
|
|
335
|
+
try:
|
|
336
|
+
features, artifact_url = _handle_featureset_validation(
|
|
337
|
+
featureset=featureset, data_source_limit=data_source_limit
|
|
338
|
+
)
|
|
339
|
+
except Exception as e:
|
|
340
|
+
print(str(e))
|
|
341
|
+
|
|
342
|
+
if not ignore_validation_errors:
|
|
343
|
+
print("Not continuing to registration due to failure in validation")
|
|
344
|
+
exit(1)
|
|
345
|
+
else:
|
|
346
|
+
print("Ignoring validation errors")
|
|
347
|
+
else:
|
|
348
|
+
print(f"Skipping validation for '{featureset.name}' feature set")
|
|
349
|
+
return features, artifact_url
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
def print_validation_outputs(stdout: str, stderr: str) -> bool:
|
|
353
|
+
did_print = False
|
|
354
|
+
|
|
355
|
+
if stdout or stderr:
|
|
356
|
+
message = "Validation outputs: "
|
|
357
|
+
|
|
358
|
+
if stdout:
|
|
359
|
+
message += f"stdout: {stdout}\n "
|
|
360
|
+
|
|
361
|
+
if stderr:
|
|
362
|
+
message += f"stderr: {stderr}"
|
|
363
|
+
|
|
364
|
+
print(message)
|
|
365
|
+
did_print = True
|
|
366
|
+
|
|
367
|
+
return did_print
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import List, Optional, Tuple
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
from qwak.clients.feature_store import FeatureRegistryClient
|
|
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
|
+
@click.option(
|
|
56
|
+
"--fs-validation-ds-limit",
|
|
57
|
+
type=click.IntRange(1, 10000),
|
|
58
|
+
help="Limit the number of records to be fetched from each datasource during featureset validation",
|
|
59
|
+
)
|
|
60
|
+
def register_fs_objects(
|
|
61
|
+
path: Path,
|
|
62
|
+
force: bool,
|
|
63
|
+
no_validation: bool,
|
|
64
|
+
ignore_validation_errors: bool,
|
|
65
|
+
fs_validation_ds_limit: Optional[int],
|
|
66
|
+
**kwargs,
|
|
67
|
+
):
|
|
68
|
+
qwak_python_files: List[Tuple[str, str]]
|
|
69
|
+
|
|
70
|
+
if not path:
|
|
71
|
+
path = Path.cwd()
|
|
72
|
+
else:
|
|
73
|
+
path = Path(path)
|
|
74
|
+
|
|
75
|
+
if path.is_file():
|
|
76
|
+
qwak_python_files = [(str(path), os.path.abspath(path))]
|
|
77
|
+
elif Path.is_dir(path):
|
|
78
|
+
with qwak_spinner(
|
|
79
|
+
begin_text="Recursively looking for python files in input dir",
|
|
80
|
+
print_callback=print,
|
|
81
|
+
) as sp:
|
|
82
|
+
qwak_python_files = list_qwak_python_files(path, sp)
|
|
83
|
+
|
|
84
|
+
try:
|
|
85
|
+
import git
|
|
86
|
+
|
|
87
|
+
git_commit = git.Repo(path, search_parent_directories=True).head.commit.hexsha
|
|
88
|
+
except Exception:
|
|
89
|
+
# be super defensive on Git errors. Failing to fetch anything git related should not fail the registration
|
|
90
|
+
git_commit = None
|
|
91
|
+
|
|
92
|
+
registry_client = FeatureRegistryClient()
|
|
93
|
+
_register_entities(qwak_python_files, registry_client, force)
|
|
94
|
+
|
|
95
|
+
_register_data_sources(
|
|
96
|
+
qwak_python_files,
|
|
97
|
+
registry_client,
|
|
98
|
+
force,
|
|
99
|
+
no_validation,
|
|
100
|
+
ignore_validation_errors,
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
_register_features_sets(
|
|
104
|
+
qwak_python_files,
|
|
105
|
+
registry_client,
|
|
106
|
+
force,
|
|
107
|
+
git_commit,
|
|
108
|
+
no_validation,
|
|
109
|
+
ignore_validation_errors,
|
|
110
|
+
fs_validation_ds_limit,
|
|
111
|
+
)
|
|
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,39 @@
|
|
|
1
|
+
import click
|
|
2
|
+
from _qwak_proto.qwak.feature_store.features.feature_set_service_pb2 import (
|
|
3
|
+
RunBatchFeatureSetResponse,
|
|
4
|
+
)
|
|
5
|
+
from qwak.clients.feature_store import FeatureRegistryClient
|
|
6
|
+
from qwak.exceptions import QwakException
|
|
7
|
+
|
|
8
|
+
from qwak_sdk.inner.tools.cli_tools import QwakCommand
|
|
9
|
+
from qwak_sdk.tools.colors import Color
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@click.command(
|
|
13
|
+
"trigger", cls=QwakCommand, help="Trigger a batch feature set job ingestion job"
|
|
14
|
+
)
|
|
15
|
+
@click.argument("name")
|
|
16
|
+
def trigger_feature_set(name, **kwargs):
|
|
17
|
+
"""
|
|
18
|
+
Trigger a batch feature set ingestion job
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
name: Feature set name that will be triggered.
|
|
22
|
+
"""
|
|
23
|
+
try:
|
|
24
|
+
result: RunBatchFeatureSetResponse = FeatureRegistryClient().run_feature_set(
|
|
25
|
+
feature_set_name=name
|
|
26
|
+
)
|
|
27
|
+
except Exception as e:
|
|
28
|
+
print(
|
|
29
|
+
f"{Color.RED} Failed to trigger a batch feature set ingestion for feature set {name} {Color.END}"
|
|
30
|
+
)
|
|
31
|
+
raise QwakException(
|
|
32
|
+
f"Failed to trigger a batch feature set ingestion for feature set {name}"
|
|
33
|
+
) from e
|
|
34
|
+
|
|
35
|
+
print(
|
|
36
|
+
f"{Color.GREEN}Successfully triggered a batch feature set ingestion for feature set: {Color.YELLOW}{name}"
|
|
37
|
+
)
|
|
38
|
+
if result.execution_id:
|
|
39
|
+
print(f"{Color.WHITE} Execution ID: {Color.YELLOW}{result.execution_id}")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from typing import Tuple
|
|
2
|
+
|
|
3
|
+
from qwak.inner.build_config.build_config_v1 import BuildConfigV1
|
|
4
|
+
from qwak.inner.build_logic.interface.build_phase import BuildPhase
|
|
5
|
+
from qwak.inner.build_logic.phases.phases_pipeline import PhasesPipeline
|
|
6
|
+
from qwak.inner.build_logic.trigger_build_context import TriggerBuildContext
|
|
7
|
+
|
|
8
|
+
from .client_logs.messages import SUCCESS_MSG_REMOTE_WITH_DEPLOY, SUCCESS_MSG_REMOTE
|
|
9
|
+
from .phase.a_fetch_model_code import get_fetch_model_code_steps
|
|
10
|
+
from .phase.b_remote_register_qwak_build import get_remote_register_qwak_build_steps
|
|
11
|
+
from .phase.c_deploy import get_deploy_steps
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def remote_build_steps(config: BuildConfigV1) -> PhasesPipeline:
|
|
15
|
+
steps_root = PhasesPipeline(config=config, context=TriggerBuildContext())
|
|
16
|
+
steps_root.add_phase(
|
|
17
|
+
steps=get_fetch_model_code_steps(),
|
|
18
|
+
build_phase=BuildPhase(phase_id="FETCHING_MODEL_CODE"),
|
|
19
|
+
)
|
|
20
|
+
steps_root.add_phase(
|
|
21
|
+
steps=get_remote_register_qwak_build_steps(),
|
|
22
|
+
build_phase=BuildPhase(phase_id="REGISTERING_QWAK_BUILD"),
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
if config.deploy:
|
|
26
|
+
steps_root.add_phase(
|
|
27
|
+
steps=get_deploy_steps(),
|
|
28
|
+
build_phase=BuildPhase(phase_id="DEPLOYING_PHASE", name="Deploying", description="Deploying"),
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
return steps_root
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def create_pipeline(
|
|
35
|
+
config: BuildConfigV1,
|
|
36
|
+
) -> Tuple[PhasesPipeline, str]:
|
|
37
|
+
success_message = (
|
|
38
|
+
SUCCESS_MSG_REMOTE_WITH_DEPLOY if config.deploy else SUCCESS_MSG_REMOTE
|
|
39
|
+
)
|
|
40
|
+
pipeline = remote_build_steps(config)
|
|
41
|
+
|
|
42
|
+
return pipeline, success_message
|
|
File without changes
|