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,19 @@
|
|
|
1
|
+
import click
|
|
2
|
+
|
|
3
|
+
from qwak_sdk.commands.secrets.delete.ui import delete_secret
|
|
4
|
+
from qwak_sdk.commands.secrets.get.ui import get_secret
|
|
5
|
+
from qwak_sdk.commands.secrets.set.ui import set_secret
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@click.group(
|
|
9
|
+
"secrets",
|
|
10
|
+
help="Commands for interacting with the secret store",
|
|
11
|
+
)
|
|
12
|
+
def secrets_commands_group():
|
|
13
|
+
# Click commands group injection
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
secrets_commands_group.add_command(set_secret)
|
|
18
|
+
secrets_commands_group.add_command(get_secret)
|
|
19
|
+
secrets_commands_group.add_command(delete_secret)
|
|
File without changes
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import click
|
|
2
|
+
|
|
3
|
+
from qwak_sdk.commands.secrets.set._logic import execute_set_secret
|
|
4
|
+
from qwak_sdk.inner.tools.cli_tools import QwakCommand
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@click.command("set", cls=QwakCommand)
|
|
8
|
+
@click.option("--name", metavar="TEXT", required=True, help="the secret name")
|
|
9
|
+
@click.option("--value", hide_input=True, confirmation_prompt=False, prompt=True)
|
|
10
|
+
def set_secret(name, value, **kwargs):
|
|
11
|
+
print(f"Creating secret named '{name}' with value length of {len(value)}...")
|
|
12
|
+
try:
|
|
13
|
+
execute_set_secret(name, value)
|
|
14
|
+
print("Created!")
|
|
15
|
+
except Exception as e:
|
|
16
|
+
print(f"Error setting secret. Error is {e}")
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from typing import Any, Callable, Iterable, List
|
|
2
|
+
|
|
3
|
+
from google.protobuf.json_format import MessageToJson
|
|
4
|
+
from tabulate import tabulate
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def output_as_json(data: Any):
|
|
8
|
+
print(MessageToJson(data))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def output_as_table(
|
|
12
|
+
data_source: Iterable[Any], data_extractor: Callable, headers: List[str]
|
|
13
|
+
):
|
|
14
|
+
data = []
|
|
15
|
+
for item in data_source:
|
|
16
|
+
data.append(data_extractor(item))
|
|
17
|
+
|
|
18
|
+
print(tabulate(data, headers=headers))
|
|
File without changes
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from .base import QwakConfigBase, YamlConfigMixin
|
|
2
|
+
from .utils import (
|
|
3
|
+
ConfigCliMap,
|
|
4
|
+
validate_bool,
|
|
5
|
+
validate_enum,
|
|
6
|
+
validate_float,
|
|
7
|
+
validate_int,
|
|
8
|
+
validate_list_of_strings,
|
|
9
|
+
validate_string,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"QwakConfigBase",
|
|
14
|
+
"YamlConfigMixin",
|
|
15
|
+
"ConfigCliMap",
|
|
16
|
+
"validate_bool",
|
|
17
|
+
"validate_enum",
|
|
18
|
+
"validate_float",
|
|
19
|
+
"validate_int",
|
|
20
|
+
"validate_list_of_strings",
|
|
21
|
+
"validate_string",
|
|
22
|
+
]
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import Any, Dict, List, Tuple
|
|
4
|
+
|
|
5
|
+
from marshmallow_dataclass import class_schema
|
|
6
|
+
from qwak.exceptions import QwakException
|
|
7
|
+
from yaml import Loader, dump, load
|
|
8
|
+
|
|
9
|
+
from qwak_sdk.common.run_config.utils import ConfigCliMap, rgetattr, rsetattr
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class QwakConfigBase(ABC):
|
|
13
|
+
"""Base qwak config object."""
|
|
14
|
+
|
|
15
|
+
@property
|
|
16
|
+
@abstractmethod
|
|
17
|
+
def _config_mapping(self) -> List[ConfigCliMap]:
|
|
18
|
+
"""Config mapping, Return a list of ConfigCliMap object in order to create the mapping.
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
list: List of ConfigCliMap to apply.
|
|
22
|
+
"""
|
|
23
|
+
pass
|
|
24
|
+
|
|
25
|
+
def merge_cli_argument(
|
|
26
|
+
self, sections: Tuple[str, ...] = (), **kwargs: Dict[str, Any]
|
|
27
|
+
):
|
|
28
|
+
"""Merge and validate cli arguments by supplied mapping.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
sections: Sections to validate.
|
|
32
|
+
**kwargs: argument from cli.
|
|
33
|
+
|
|
34
|
+
Raises:
|
|
35
|
+
QwakException: In case that the argument is not valid.
|
|
36
|
+
"""
|
|
37
|
+
for prop_map in self._config_mapping:
|
|
38
|
+
value = kwargs.get(prop_map.key)
|
|
39
|
+
if value is not None:
|
|
40
|
+
if isinstance(value, (list, tuple)):
|
|
41
|
+
new_value = list(rgetattr(self, prop_map.prop))
|
|
42
|
+
new_value.extend(value)
|
|
43
|
+
value = new_value
|
|
44
|
+
rsetattr(self, prop_map.prop, value)
|
|
45
|
+
if (
|
|
46
|
+
not sections
|
|
47
|
+
or any(
|
|
48
|
+
list(
|
|
49
|
+
map(
|
|
50
|
+
lambda section, _prop_map=prop_map: _prop_map.prop.startswith(
|
|
51
|
+
section
|
|
52
|
+
),
|
|
53
|
+
sections,
|
|
54
|
+
)
|
|
55
|
+
)
|
|
56
|
+
)
|
|
57
|
+
or "." not in prop_map.prop
|
|
58
|
+
):
|
|
59
|
+
config_value = rgetattr(self, prop_map.prop)
|
|
60
|
+
if not prop_map.validation_func(config_value, prop_map.is_required):
|
|
61
|
+
raise QwakException(
|
|
62
|
+
f"{prop_map.key} argument contain invalid argument: "
|
|
63
|
+
f"{value or config_value}"
|
|
64
|
+
)
|
|
65
|
+
self._post_merge_cli()
|
|
66
|
+
|
|
67
|
+
@abstractmethod
|
|
68
|
+
def _post_merge_cli(self):
|
|
69
|
+
"""Actions to perform after merging cli argument in to properties"""
|
|
70
|
+
pass
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class YamlConfigMixin(object):
|
|
74
|
+
@classmethod
|
|
75
|
+
def from_yaml(cls, yaml_path: str) -> Any:
|
|
76
|
+
"""Create instance of class from yaml and class scheme.
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
yaml_path (str): Yaml path.
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
object: Instance of created class.
|
|
83
|
+
"""
|
|
84
|
+
if not yaml_path:
|
|
85
|
+
return cls()
|
|
86
|
+
schema = class_schema(cls)
|
|
87
|
+
yaml_content = Path(yaml_path).read_text()
|
|
88
|
+
yaml_parsed = load(stream=yaml_content, Loader=Loader)
|
|
89
|
+
|
|
90
|
+
return schema().load(yaml_parsed)
|
|
91
|
+
|
|
92
|
+
def to_yaml(self) -> str:
|
|
93
|
+
"""Convert class by scheme to yaml.
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
str: Class as yaml string by scheme.
|
|
97
|
+
"""
|
|
98
|
+
loaded_type = type(self)
|
|
99
|
+
schema = class_schema(loaded_type)
|
|
100
|
+
|
|
101
|
+
return dump(schema().dump(self))
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import functools
|
|
2
|
+
from collections.abc import Iterable
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
|
+
from typing import Any, Callable
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@dataclass
|
|
8
|
+
class ConfigCliMap:
|
|
9
|
+
"""Mapping between cli argument to properties argument.
|
|
10
|
+
|
|
11
|
+
Attributes:
|
|
12
|
+
key (str): key of the argument in the cli.
|
|
13
|
+
prop (str): property path as nested json object (obj.prop1.prop2)
|
|
14
|
+
validation_func (Callable): function which accept two parameters value (value to validate and is_required param.
|
|
15
|
+
is_required (bool): True if value is required else False.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
key: str
|
|
19
|
+
prop: str
|
|
20
|
+
validation_func: Callable = field(default=lambda: True)
|
|
21
|
+
is_required: bool = False
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def validate_list_of_strings(value: Any, is_required: bool) -> bool:
|
|
25
|
+
"""Validate if a list include only strings
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
value: Value to perform validation on.
|
|
29
|
+
is_required: True if value is required.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
bool: True if value is valid.
|
|
33
|
+
|
|
34
|
+
Examples:
|
|
35
|
+
>>> validate_list_of_strings(["1", "3"], False)
|
|
36
|
+
True
|
|
37
|
+
>>> validate_list_of_strings(["1", 3], False)
|
|
38
|
+
False
|
|
39
|
+
>>> validate_list_of_strings(None, True)
|
|
40
|
+
False
|
|
41
|
+
"""
|
|
42
|
+
if not value and not is_required:
|
|
43
|
+
return True
|
|
44
|
+
elif not isinstance(value, Iterable):
|
|
45
|
+
return False
|
|
46
|
+
|
|
47
|
+
return all(isinstance(p, str) for p in value)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def validate_string(value: Any, is_required: bool) -> bool:
|
|
51
|
+
"""Validate if value is a string.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
value: Value to perform validation on.
|
|
55
|
+
is_required: True if value is required.
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
bool: True if value is valid.
|
|
59
|
+
|
|
60
|
+
Examples:
|
|
61
|
+
>>> validate_string("3", False)
|
|
62
|
+
True
|
|
63
|
+
>>> validate_string(3, False)
|
|
64
|
+
False
|
|
65
|
+
>>> validate_string(None, True)
|
|
66
|
+
False
|
|
67
|
+
"""
|
|
68
|
+
if value:
|
|
69
|
+
return isinstance(value, str)
|
|
70
|
+
elif is_required:
|
|
71
|
+
return False
|
|
72
|
+
|
|
73
|
+
return True
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def validate_float(value: Any, is_required: bool) -> bool:
|
|
77
|
+
"""Validate if value is a float.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
value: Value to perform validation on.
|
|
81
|
+
is_required: True if value is required.
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
bool: True if value is valid.
|
|
85
|
+
|
|
86
|
+
Examples:
|
|
87
|
+
>>> validate_float(3, True)
|
|
88
|
+
True
|
|
89
|
+
>>> validate_float(3.5, True)
|
|
90
|
+
True
|
|
91
|
+
>>> validate_float(None, True)
|
|
92
|
+
False
|
|
93
|
+
"""
|
|
94
|
+
if value:
|
|
95
|
+
return isinstance(value, (float, int))
|
|
96
|
+
elif is_required:
|
|
97
|
+
return False
|
|
98
|
+
|
|
99
|
+
return True
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def validate_int(value: Any, is_required: bool) -> bool:
|
|
103
|
+
"""Validate if value is a int.
|
|
104
|
+
|
|
105
|
+
Args:
|
|
106
|
+
value: Value to perform validation on.
|
|
107
|
+
is_required: True if value is required.
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
bool: True if value is valid.
|
|
111
|
+
|
|
112
|
+
Examples:
|
|
113
|
+
>>> validate_int(3, True)
|
|
114
|
+
True
|
|
115
|
+
>>> validate_int(3.5, True)
|
|
116
|
+
False
|
|
117
|
+
>>> validate_int(None, True)
|
|
118
|
+
False
|
|
119
|
+
"""
|
|
120
|
+
if value:
|
|
121
|
+
return isinstance(value, int) or (isinstance(value, str) and value.isdigit())
|
|
122
|
+
elif is_required:
|
|
123
|
+
return False
|
|
124
|
+
|
|
125
|
+
return True
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def validate_bool(value: Any, is_required: bool) -> bool:
|
|
129
|
+
"""Validate if value is a boolean.
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
value: Value to perform validation on.
|
|
133
|
+
is_required: True if value is required.
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
bool: True if value is valid.
|
|
137
|
+
|
|
138
|
+
Examples:
|
|
139
|
+
>>> validate_bool(True, False)
|
|
140
|
+
True
|
|
141
|
+
>>> validate_bool("true", False)
|
|
142
|
+
False
|
|
143
|
+
>>> validate_bool(None, True)
|
|
144
|
+
False
|
|
145
|
+
"""
|
|
146
|
+
if isinstance(value, bool):
|
|
147
|
+
return True
|
|
148
|
+
elif is_required:
|
|
149
|
+
return False
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def validate_enum(enum: Any) -> Callable:
|
|
153
|
+
"""Create function to validate if value in enum.
|
|
154
|
+
|
|
155
|
+
Args:
|
|
156
|
+
enum: enum to validate on
|
|
157
|
+
|
|
158
|
+
Returns:
|
|
159
|
+
bool: Callable.
|
|
160
|
+
"""
|
|
161
|
+
|
|
162
|
+
def validate(value: Any, is_required: bool) -> bool:
|
|
163
|
+
if value and isinstance(value, str):
|
|
164
|
+
return value.upper() in enum.__members__
|
|
165
|
+
elif is_required:
|
|
166
|
+
return False
|
|
167
|
+
|
|
168
|
+
return True
|
|
169
|
+
|
|
170
|
+
return validate
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def validate_variation(value: Any) -> bool:
|
|
174
|
+
"""
|
|
175
|
+
Args:
|
|
176
|
+
value: value to perform validation on.
|
|
177
|
+
|
|
178
|
+
Returns:
|
|
179
|
+
bool: True if value is valid.
|
|
180
|
+
"""
|
|
181
|
+
if not (hasattr(value, "name") and isinstance(value.name, str)):
|
|
182
|
+
return False
|
|
183
|
+
|
|
184
|
+
if not hasattr(value, "traffic"):
|
|
185
|
+
return False
|
|
186
|
+
|
|
187
|
+
if not (
|
|
188
|
+
hasattr(value.traffic, "percentage")
|
|
189
|
+
and isinstance(value.traffic.percentage, int)
|
|
190
|
+
):
|
|
191
|
+
return False
|
|
192
|
+
|
|
193
|
+
if not (
|
|
194
|
+
hasattr(value.traffic, "shadow") and isinstance(value.traffic.shadow, bool)
|
|
195
|
+
):
|
|
196
|
+
return False
|
|
197
|
+
|
|
198
|
+
return True
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def validate_variations(value: Any, is_required: bool) -> bool:
|
|
202
|
+
"""Validate if value is a variation.
|
|
203
|
+
|
|
204
|
+
Args:
|
|
205
|
+
value: Value to perform validation on.
|
|
206
|
+
|
|
207
|
+
Returns:
|
|
208
|
+
bool: True if value is valid.
|
|
209
|
+
|
|
210
|
+
Examples:
|
|
211
|
+
>>> validate_variations([DeployConfig.Realtime.VariationConfig(name='default', traffic=DeployConfig.Realtime.VariationConfig.TrafficConfig(percentage=100, shadow=False))], False)
|
|
212
|
+
True
|
|
213
|
+
>>> validate_variations(["{variation.name: Test}"], False)
|
|
214
|
+
False
|
|
215
|
+
>>> validate_variations(None, True)
|
|
216
|
+
False
|
|
217
|
+
"""
|
|
218
|
+
if not value and not is_required:
|
|
219
|
+
return True
|
|
220
|
+
elif not isinstance(value, Iterable):
|
|
221
|
+
return False
|
|
222
|
+
|
|
223
|
+
return all(validate_variation(variation) for variation in value)
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def rsetattr(obj: object, attr: str, val: Any):
|
|
227
|
+
"""Set attribute in object recursively.
|
|
228
|
+
|
|
229
|
+
Args:
|
|
230
|
+
obj: Object to set value in.
|
|
231
|
+
attr: Nested attributes path to value. (obj.prop1.prop2)
|
|
232
|
+
val: Value to set in property
|
|
233
|
+
"""
|
|
234
|
+
pre, _, post = attr.rpartition(".")
|
|
235
|
+
setattr(rgetattr(obj, pre) if pre else obj, post, val)
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def rgetattr(obj: object, attr: str, *args) -> Any:
|
|
239
|
+
"""Get attribute in object recursively.
|
|
240
|
+
|
|
241
|
+
Args:
|
|
242
|
+
obj: Object to set value in.
|
|
243
|
+
attr: Nested attributes path to value. (obj.prop1.prop2)
|
|
244
|
+
"""
|
|
245
|
+
|
|
246
|
+
def _getattr(obj, attr):
|
|
247
|
+
return getattr(obj, attr, *args)
|
|
248
|
+
|
|
249
|
+
return functools.reduce(_getattr, [obj] + attr.split("."))
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from .qwak_command_exception import QwakCommandException
|
|
2
|
+
from .qwak_general_build_exception import QwakGeneralBuildException
|
|
3
|
+
from .qwak_resource_not_found import QwakResourceNotFound
|
|
4
|
+
from .qwak_suggestion_exception import QwakSuggestionException
|
|
5
|
+
|
|
6
|
+
__all__ = [
|
|
7
|
+
"QwakGeneralBuildException",
|
|
8
|
+
"QwakSuggestionException",
|
|
9
|
+
"QwakResourceNotFound",
|
|
10
|
+
"QwakCommandException",
|
|
11
|
+
]
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
class QwakGeneralBuildException(Exception):
|
|
2
|
+
def __init__(self, message: str, src_exception: Exception = None):
|
|
3
|
+
self._message = message
|
|
4
|
+
self._exception_msg = str(src_exception) if src_exception else ""
|
|
5
|
+
|
|
6
|
+
@property
|
|
7
|
+
def message(self) -> str:
|
|
8
|
+
msg = f"""Message: {self._message}
|
|
9
|
+
Exception message: {self._exception_msg}"""
|
|
10
|
+
return msg
|
|
11
|
+
|
|
12
|
+
def __str__(self):
|
|
13
|
+
return self.message
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class QwakSuggestionException(Exception):
|
|
5
|
+
def __init__(
|
|
6
|
+
self,
|
|
7
|
+
message: str,
|
|
8
|
+
src_exception: Optional[Exception] = None,
|
|
9
|
+
suggestion: Optional[str] = "",
|
|
10
|
+
):
|
|
11
|
+
self._message = message
|
|
12
|
+
self._src_exception = str(src_exception) if src_exception else ""
|
|
13
|
+
self._suggestion = suggestion
|
|
14
|
+
|
|
15
|
+
@property
|
|
16
|
+
def message(self) -> str:
|
|
17
|
+
if self._src_exception:
|
|
18
|
+
msg = f"""Message: {self._message}.
|
|
19
|
+
Exception message: {self._src_exception}.
|
|
20
|
+
Recommendation: {self._suggestion}."""
|
|
21
|
+
else:
|
|
22
|
+
msg = f"""Message: {self._message}.
|
|
23
|
+
Recommendation: {self._suggestion}."""
|
|
24
|
+
return msg
|
|
25
|
+
|
|
26
|
+
def __str__(self):
|
|
27
|
+
return self.message
|
|
File without changes
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import importlib.util
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
from contextlib import contextmanager
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from yaspin.core import Yaspin
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def list_qwak_python_files(path: Path, sp: Yaspin):
|
|
11
|
+
"""
|
|
12
|
+
Helper function which finds python files with qwak imports in a given module
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
path: path to a directory
|
|
16
|
+
sp: spinner object, used to print
|
|
17
|
+
Returns:
|
|
18
|
+
List of python files which use the Qwak SDK
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
file_paths = []
|
|
22
|
+
if Path.is_dir(path):
|
|
23
|
+
for object_path in path.glob("**/*.py"):
|
|
24
|
+
try:
|
|
25
|
+
if not object_path.is_file():
|
|
26
|
+
continue
|
|
27
|
+
mod_name, file_ext = os.path.splitext(object_path.name)
|
|
28
|
+
if file_ext != ".py" or mod_name == "setup":
|
|
29
|
+
continue
|
|
30
|
+
|
|
31
|
+
with object_path.open("rb") as fp:
|
|
32
|
+
content = fp.read()
|
|
33
|
+
contains_qwak_feature = all(
|
|
34
|
+
[token in content for token in (b"qwak")]
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
if not contains_qwak_feature:
|
|
38
|
+
continue
|
|
39
|
+
|
|
40
|
+
with _add_to_python_path(object_path):
|
|
41
|
+
# Test that the file can be imported cleanly
|
|
42
|
+
spec = importlib.util.spec_from_file_location(mod_name, object_path)
|
|
43
|
+
if not spec:
|
|
44
|
+
sp.write(f"Could not load file: {object_path}. Skipping.")
|
|
45
|
+
continue
|
|
46
|
+
module = importlib.util.module_from_spec(spec)
|
|
47
|
+
spec.loader.exec_module(module)
|
|
48
|
+
|
|
49
|
+
file_paths.append((mod_name, object_path))
|
|
50
|
+
except Exception as e:
|
|
51
|
+
sp.write(
|
|
52
|
+
f"Got an error trying to handle the file {object_path}, error is: {e}. Skipping."
|
|
53
|
+
)
|
|
54
|
+
return file_paths
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def extract_class_objects(python_files, clazz):
|
|
58
|
+
"""
|
|
59
|
+
Helper function which given a list of python files extracts objects of the type `clazz`
|
|
60
|
+
|
|
61
|
+
Args
|
|
62
|
+
python_files: list of python files
|
|
63
|
+
clazz: class object which its instances should be extracted
|
|
64
|
+
Returns
|
|
65
|
+
list of extracted objects of type clazz from the given python files
|
|
66
|
+
"""
|
|
67
|
+
clazz_objects = []
|
|
68
|
+
for mod, file in python_files:
|
|
69
|
+
with _add_to_python_path(Path(file)):
|
|
70
|
+
spec = importlib.util.spec_from_file_location(mod, file)
|
|
71
|
+
if not spec:
|
|
72
|
+
continue
|
|
73
|
+
|
|
74
|
+
module = importlib.util.module_from_spec(spec)
|
|
75
|
+
spec.loader.exec_module(module)
|
|
76
|
+
for feature in list(module.__dict__.values()):
|
|
77
|
+
if isinstance(feature, clazz):
|
|
78
|
+
clazz_objects.append((feature, file))
|
|
79
|
+
|
|
80
|
+
return clazz_objects
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@contextmanager
|
|
84
|
+
def _add_to_python_path(path: Path):
|
|
85
|
+
"""
|
|
86
|
+
Helper function - context adding path to python path and then remove it
|
|
87
|
+
|
|
88
|
+
Args
|
|
89
|
+
path: path of file or folder to add to python path, in case of file adds the containing folder
|
|
90
|
+
Returns
|
|
91
|
+
"""
|
|
92
|
+
try:
|
|
93
|
+
folder = str(path.parent) if path.is_file() else str(path)
|
|
94
|
+
sys.path.append(folder)
|
|
95
|
+
yield
|
|
96
|
+
finally:
|
|
97
|
+
sys.path.remove(folder)
|
|
File without changes
|