frogml-cli 0.0.1__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.
- frogml_cli/__init__.py +10 -0
- frogml_cli/cli.py +40 -0
- frogml_cli/commands/__init__.py +0 -0
- frogml_cli/commands/_logic/__init__.py +0 -0
- frogml_cli/commands/_logic/tools.py +6 -0
- frogml_cli/commands/alerts/__init__.py +0 -0
- frogml_cli/commands/alerts/alerts_commnad_group.py +18 -0
- frogml_cli/commands/alerts/delete/__init__.py +0 -0
- frogml_cli/commands/alerts/delete/_logic.py +5 -0
- frogml_cli/commands/alerts/delete/ui.py +10 -0
- frogml_cli/commands/alerts/list/__init__.py +0 -0
- frogml_cli/commands/alerts/list/_logic.py +23 -0
- frogml_cli/commands/alerts/list/ui.py +17 -0
- frogml_cli/commands/alerts/register/__init__.py +0 -0
- frogml_cli/commands/alerts/register/_logic.py +72 -0
- frogml_cli/commands/alerts/register/ui.py +30 -0
- frogml_cli/commands/audience/__init__.py +0 -0
- frogml_cli/commands/audience/_logic/__init__.py +0 -0
- frogml_cli/commands/audience/_logic/config/__init__.py +0 -0
- frogml_cli/commands/audience/_logic/config/config_base.py +15 -0
- frogml_cli/commands/audience/_logic/config/parser.py +30 -0
- frogml_cli/commands/audience/_logic/config/v1/__init__.py +0 -0
- frogml_cli/commands/audience/_logic/config/v1/audience_config.py +25 -0
- frogml_cli/commands/audience/_logic/config/v1/conditions_config.py +59 -0
- frogml_cli/commands/audience/_logic/config/v1/config_v1.py +23 -0
- frogml_cli/commands/audience/_logic/config/v1/route_config.py +15 -0
- frogml_cli/commands/audience/_logic/config/v1/spec.py +9 -0
- frogml_cli/commands/audience/audience_api_dump.py +86 -0
- frogml_cli/commands/audience/audience_commands_group.py +30 -0
- frogml_cli/commands/audience/create/__init__.py +0 -0
- frogml_cli/commands/audience/create/logic.py +41 -0
- frogml_cli/commands/audience/create/ui.py +21 -0
- frogml_cli/commands/audience/delete/__init__.py +0 -0
- frogml_cli/commands/audience/delete/logic.py +13 -0
- frogml_cli/commands/audience/delete/ui.py +17 -0
- frogml_cli/commands/audience/get/__init__.py +0 -0
- frogml_cli/commands/audience/get/logic.py +14 -0
- frogml_cli/commands/audience/get/ui.py +25 -0
- frogml_cli/commands/audience/list/__init__.py +0 -0
- frogml_cli/commands/audience/list/logic.py +16 -0
- frogml_cli/commands/audience/list/ui.py +26 -0
- frogml_cli/commands/audience/update/__init__.py +0 -0
- frogml_cli/commands/audience/update/logic.py +37 -0
- frogml_cli/commands/audience/update/ui.py +26 -0
- frogml_cli/commands/auto_scalling/__init__.py +0 -0
- frogml_cli/commands/auto_scalling/_logic/__init__.py +0 -0
- frogml_cli/commands/auto_scalling/_logic/config/__init__.py +3 -0
- frogml_cli/commands/auto_scalling/_logic/config/config.py +152 -0
- frogml_cli/commands/auto_scalling/_logic/config/parser.py +21 -0
- frogml_cli/commands/auto_scalling/attach/__init__.py +0 -0
- frogml_cli/commands/auto_scalling/attach/_logic.py +43 -0
- frogml_cli/commands/auto_scalling/attach/ui.py +21 -0
- frogml_cli/commands/auto_scalling/autoscaling_commands_group.py +15 -0
- frogml_cli/commands/automations/__init__.py +0 -0
- frogml_cli/commands/automations/automations_commands_group.py +30 -0
- frogml_cli/commands/automations/delete/__init__.py +0 -0
- frogml_cli/commands/automations/delete/_logic.py +6 -0
- frogml_cli/commands/automations/delete/ui.py +23 -0
- frogml_cli/commands/automations/executions/__init__.py +0 -0
- frogml_cli/commands/automations/executions/executions_commands_group.py +14 -0
- frogml_cli/commands/automations/executions/list/__init__.py +0 -0
- frogml_cli/commands/automations/executions/list/_logic.py +8 -0
- frogml_cli/commands/automations/executions/list/ui.py +27 -0
- frogml_cli/commands/automations/list/__init__.py +0 -0
- frogml_cli/commands/automations/list/_logic.py +36 -0
- frogml_cli/commands/automations/list/ui.py +21 -0
- frogml_cli/commands/automations/register/__init__.py +0 -0
- frogml_cli/commands/automations/register/_logic.py +43 -0
- frogml_cli/commands/automations/register/ui.py +44 -0
- frogml_cli/commands/config/__init__.py +0 -0
- frogml_cli/commands/config/add/__init__.py +0 -0
- frogml_cli/commands/config/add/ui.py +62 -0
- frogml_cli/commands/config/config_commands_group.py +11 -0
- frogml_cli/commands/feature_store/__init__.py +0 -0
- frogml_cli/commands/feature_store/backfill/__init__.py +0 -0
- frogml_cli/commands/feature_store/backfill/_logic.py +140 -0
- frogml_cli/commands/feature_store/backfill/ui.py +129 -0
- frogml_cli/commands/feature_store/delete/__init__.py +0 -0
- frogml_cli/commands/feature_store/delete/_logic.py +107 -0
- frogml_cli/commands/feature_store/delete/ui.py +40 -0
- frogml_cli/commands/feature_store/execution/__init__.py +0 -0
- frogml_cli/commands/feature_store/execution/ui.py +19 -0
- frogml_cli/commands/feature_store/feature_store_command_group.py +29 -0
- frogml_cli/commands/feature_store/list/__init__.py +0 -0
- frogml_cli/commands/feature_store/list/ui.py +140 -0
- frogml_cli/commands/feature_store/pause/__init__.py +0 -0
- frogml_cli/commands/feature_store/pause/ui.py +18 -0
- frogml_cli/commands/feature_store/register/__init__.py +0 -0
- frogml_cli/commands/feature_store/register/_logic.py +369 -0
- frogml_cli/commands/feature_store/register/ui.py +111 -0
- frogml_cli/commands/feature_store/resume/__init__.py +0 -0
- frogml_cli/commands/feature_store/resume/ui.py +18 -0
- frogml_cli/commands/feature_store/trigger/__init__.py +0 -0
- frogml_cli/commands/feature_store/trigger/ui.py +39 -0
- frogml_cli/commands/models/__init__.py +0 -0
- frogml_cli/commands/models/build/__init__.py +0 -0
- frogml_cli/commands/models/build/_logic/__init__.py +0 -0
- frogml_cli/commands/models/build/_logic/build_steps.py +42 -0
- frogml_cli/commands/models/build/_logic/client_logs/__init__.py +0 -0
- frogml_cli/commands/models/build/_logic/client_logs/cli_phase_run_handler.py +123 -0
- frogml_cli/commands/models/build/_logic/client_logs/cli_trigger_build_logger.py +19 -0
- frogml_cli/commands/models/build/_logic/client_logs/logger.py +88 -0
- frogml_cli/commands/models/build/_logic/client_logs/messages.py +36 -0
- frogml_cli/commands/models/build/_logic/client_logs/spinner.py +14 -0
- frogml_cli/commands/models/build/_logic/client_logs/trigger_build_logger.py +54 -0
- frogml_cli/commands/models/build/_logic/client_logs/utils.py +12 -0
- frogml_cli/commands/models/build/_logic/phase/__init__.py +0 -0
- frogml_cli/commands/models/build/_logic/phase/a_fetch_model_code/__init__.py +20 -0
- frogml_cli/commands/models/build/_logic/phase/a_fetch_model_code/get_sdk_version_step.py +15 -0
- frogml_cli/commands/models/build/_logic/phase/b_remote_register_frogml_build/__init__.py +16 -0
- frogml_cli/commands/models/build/_logic/phase/c_deploy/__init__.py +6 -0
- frogml_cli/commands/models/build/_logic/phase/c_deploy/build_polling_status.py +55 -0
- frogml_cli/commands/models/build/_logic/phase/c_deploy/deploy_build.py +61 -0
- frogml_cli/commands/models/build/_logic/util/__init__.py +0 -0
- frogml_cli/commands/models/build/_logic/util/protobuf_factory.py +45 -0
- frogml_cli/commands/models/build/_logic/util/step_decorator.py +60 -0
- frogml_cli/commands/models/build/_logic/util/text.py +9 -0
- frogml_cli/commands/models/build/_logic/wait_until_finished.py +27 -0
- frogml_cli/commands/models/build/ui.py +337 -0
- frogml_cli/commands/models/builds/__init__.py +0 -0
- frogml_cli/commands/models/builds/builds_commands_group.py +16 -0
- frogml_cli/commands/models/builds/cancel/__init__.py +0 -0
- frogml_cli/commands/models/builds/cancel/_logic.py +5 -0
- frogml_cli/commands/models/builds/cancel/ui.py +15 -0
- frogml_cli/commands/models/builds/logs/__init__.py +0 -0
- frogml_cli/commands/models/builds/logs/ui.py +35 -0
- frogml_cli/commands/models/builds/status/__init__.py +0 -0
- frogml_cli/commands/models/builds/status/_logic.py +6 -0
- frogml_cli/commands/models/builds/status/ui.py +39 -0
- frogml_cli/commands/models/create/__init__.py +0 -0
- frogml_cli/commands/models/create/_logic.py +40 -0
- frogml_cli/commands/models/create/ui.py +46 -0
- frogml_cli/commands/models/delete/__init__.py +0 -0
- frogml_cli/commands/models/delete/_logic.py +18 -0
- frogml_cli/commands/models/delete/ui.py +25 -0
- frogml_cli/commands/models/deployments/__init__.py +0 -0
- frogml_cli/commands/models/deployments/deploy/__init__.py +0 -0
- frogml_cli/commands/models/deployments/deploy/_logic/__init__.py +0 -0
- frogml_cli/commands/models/deployments/deploy/_logic/advance_deployment_options_handler.py +31 -0
- frogml_cli/commands/models/deployments/deploy/_logic/base_deploy_executor.py +70 -0
- frogml_cli/commands/models/deployments/deploy/_logic/deploy_config.py +261 -0
- frogml_cli/commands/models/deployments/deploy/_logic/deployment.py +407 -0
- frogml_cli/commands/models/deployments/deploy/_logic/deployment_message_helpers.py +116 -0
- frogml_cli/commands/models/deployments/deploy/_logic/deployment_response_handler.py +156 -0
- frogml_cli/commands/models/deployments/deploy/_logic/deployment_size_mapper.py +98 -0
- frogml_cli/commands/models/deployments/deploy/_logic/get_latest_successful_build.py +28 -0
- frogml_cli/commands/models/deployments/deploy/_logic/local_deployment.py +193 -0
- frogml_cli/commands/models/deployments/deploy/batch/__init__.py +0 -0
- frogml_cli/commands/models/deployments/deploy/batch/_logic/__init__.py +0 -0
- frogml_cli/commands/models/deployments/deploy/batch/_logic/advanced_deployment_mapper.py +15 -0
- frogml_cli/commands/models/deployments/deploy/batch/_logic/deploy_executor.py +24 -0
- frogml_cli/commands/models/deployments/deploy/batch/ui.py +119 -0
- frogml_cli/commands/models/deployments/deploy/deploy_commands_group.py +19 -0
- frogml_cli/commands/models/deployments/deploy/realtime/__init__.py +0 -0
- frogml_cli/commands/models/deployments/deploy/realtime/_logic/__init__.py +0 -0
- frogml_cli/commands/models/deployments/deploy/realtime/_logic/advanced_deployment_mapper.py +21 -0
- frogml_cli/commands/models/deployments/deploy/realtime/_logic/deploy_executor.py +24 -0
- frogml_cli/commands/models/deployments/deploy/realtime/_logic/serving_strategy_mapper.py +75 -0
- frogml_cli/commands/models/deployments/deploy/realtime/ui.py +202 -0
- frogml_cli/commands/models/deployments/deploy/streaming/__init__.py +0 -0
- frogml_cli/commands/models/deployments/deploy/streaming/_logic/__init__.py +0 -0
- frogml_cli/commands/models/deployments/deploy/streaming/_logic/deploy_executor.py +24 -0
- frogml_cli/commands/models/deployments/deploy/streaming/_logic/serving_strategy_mapper.py +38 -0
- frogml_cli/commands/models/deployments/deploy/streaming/ui.py +206 -0
- frogml_cli/commands/models/deployments/undeploy/__init__.py +0 -0
- frogml_cli/commands/models/deployments/undeploy/_logic/__init__.py +0 -0
- frogml_cli/commands/models/deployments/undeploy/_logic/request_undeploy.py +249 -0
- frogml_cli/commands/models/deployments/undeploy/ui.py +61 -0
- frogml_cli/commands/models/describe/__init__.py +0 -0
- frogml_cli/commands/models/describe/_logic.py +169 -0
- frogml_cli/commands/models/describe/ui.py +35 -0
- frogml_cli/commands/models/executions/__init__.py +0 -0
- frogml_cli/commands/models/executions/cancel/__init__.py +0 -0
- frogml_cli/commands/models/executions/cancel/_logic.py +9 -0
- frogml_cli/commands/models/executions/cancel/ui.py +27 -0
- frogml_cli/commands/models/executions/execution_commands_group.py +24 -0
- frogml_cli/commands/models/executions/report/__init__.py +0 -0
- frogml_cli/commands/models/executions/report/_logic.py +14 -0
- frogml_cli/commands/models/executions/report/ui.py +43 -0
- frogml_cli/commands/models/executions/start/__init__.py +0 -0
- frogml_cli/commands/models/executions/start/_logic.py +83 -0
- frogml_cli/commands/models/executions/start/ui.py +208 -0
- frogml_cli/commands/models/executions/status/__init__.py +0 -0
- frogml_cli/commands/models/executions/status/_logic.py +13 -0
- frogml_cli/commands/models/executions/status/ui.py +27 -0
- frogml_cli/commands/models/init/__init__.py +0 -0
- frogml_cli/commands/models/init/_logic/__init__.py +0 -0
- frogml_cli/commands/models/init/_logic/initialize_model_structure.py +40 -0
- frogml_cli/commands/models/init/_logic/template/__init__.py +0 -0
- frogml_cli/commands/models/init/_logic/template/churn/__init__.py +0 -0
- frogml_cli/commands/models/init/_logic/template/churn/cookiecutter.json +3 -0
- frogml_cli/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/__init__.py +0 -0
- frogml_cli/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/main/__init__.py +5 -0
- frogml_cli/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/main/conda.yml +10 -0
- frogml_cli/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/main/data.csv +1001 -0
- frogml_cli/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/main/model.py +99 -0
- frogml_cli/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/tests/__init__.py +0 -0
- frogml_cli/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/tests/it/__init__.py +0 -0
- frogml_cli/commands/models/init/_logic/template/churn/{{cookiecutter.model_directory}}/tests/it/test_churn.py +32 -0
- frogml_cli/commands/models/init/_logic/template/credit_risk/__init__.py +0 -0
- frogml_cli/commands/models/init/_logic/template/credit_risk/cookiecutter.json +3 -0
- frogml_cli/commands/models/init/_logic/template/credit_risk/{{cookiecutter.model_directory}}/__init__.py +0 -0
- frogml_cli/commands/models/init/_logic/template/credit_risk/{{cookiecutter.model_directory}}/main/__init__.py +5 -0
- frogml_cli/commands/models/init/_logic/template/credit_risk/{{cookiecutter.model_directory}}/main/conda.yml +11 -0
- frogml_cli/commands/models/init/_logic/template/credit_risk/{{cookiecutter.model_directory}}/main/data.csv +1001 -0
- frogml_cli/commands/models/init/_logic/template/credit_risk/{{cookiecutter.model_directory}}/main/model.py +108 -0
- frogml_cli/commands/models/init/_logic/template/general/__init__.py +0 -0
- frogml_cli/commands/models/init/_logic/template/general/cookiecutter.json +6 -0
- frogml_cli/commands/models/init/_logic/template/general/{{cookiecutter.model_directory}}/__init__.py +0 -0
- frogml_cli/commands/models/init/_logic/template/general/{{cookiecutter.model_directory}}/{{cookiecutter.main_directory}}/__init__.py +5 -0
- frogml_cli/commands/models/init/_logic/template/general/{{cookiecutter.model_directory}}/{{cookiecutter.main_directory}}/conda.yml +8 -0
- frogml_cli/commands/models/init/_logic/template/general/{{cookiecutter.model_directory}}/{{cookiecutter.main_directory}}/model.py +66 -0
- frogml_cli/commands/models/init/_logic/template/general/{{cookiecutter.model_directory}}/{{cookiecutter.test_directory}}/__init__.py +0 -0
- frogml_cli/commands/models/init/_logic/template/general/{{cookiecutter.model_directory}}/{{cookiecutter.test_directory}}/test_qwak_model.py +5 -0
- frogml_cli/commands/models/init/_logic/template/titanic/__init__.py +0 -0
- frogml_cli/commands/models/init/_logic/template/titanic/cookiecutter.json +3 -0
- frogml_cli/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/__init__.py +0 -0
- frogml_cli/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/main/__init__.py +5 -0
- frogml_cli/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/main/conda.yml +11 -0
- frogml_cli/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/main/model.py +98 -0
- frogml_cli/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/tests/__init__.py +0 -0
- frogml_cli/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/tests/it/__init__.py +0 -0
- frogml_cli/commands/models/init/_logic/template/titanic/{{cookiecutter.model_directory}}/tests/it/test_titanic.py +24 -0
- frogml_cli/commands/models/init/_logic/template/titanic_poetry/__init__.py +0 -0
- frogml_cli/commands/models/init/_logic/template/titanic_poetry/cookiecutter.json +3 -0
- frogml_cli/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/__init__.py +0 -0
- frogml_cli/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/main/__init__.py +5 -0
- frogml_cli/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/main/model.py +98 -0
- frogml_cli/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/main/pyproject.toml +20 -0
- frogml_cli/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/tests/__init__.py +0 -0
- frogml_cli/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/tests/it/__init__.py +0 -0
- frogml_cli/commands/models/init/_logic/template/titanic_poetry/{{cookiecutter.model_directory}}/tests/it/test_titanic.py +25 -0
- frogml_cli/commands/models/init/ui.py +61 -0
- frogml_cli/commands/models/list/__init__.py +0 -0
- frogml_cli/commands/models/list/_logic.py +5 -0
- frogml_cli/commands/models/list/ui.py +41 -0
- frogml_cli/commands/models/list_models/__init__.py +0 -0
- frogml_cli/commands/models/list_models/_logic.py +11 -0
- frogml_cli/commands/models/list_models/ui.py +60 -0
- frogml_cli/commands/models/metadata/__init__.py +0 -0
- frogml_cli/commands/models/metadata/_logic.py +12 -0
- frogml_cli/commands/models/metadata/ui.py +60 -0
- frogml_cli/commands/models/models_command_group.py +44 -0
- frogml_cli/commands/models/runtime/__init__.py +0 -0
- frogml_cli/commands/models/runtime/logs/__init__.py +0 -0
- frogml_cli/commands/models/runtime/logs/ui.py +63 -0
- frogml_cli/commands/models/runtime/runtime_commands_group.py +17 -0
- frogml_cli/commands/models/runtime/update/__init__.py +0 -0
- frogml_cli/commands/models/runtime/update/_logic.py +9 -0
- frogml_cli/commands/models/runtime/update/ui.py +17 -0
- frogml_cli/commands/secrets/__init__.py +0 -0
- frogml_cli/commands/secrets/delete/__init__.py +0 -0
- frogml_cli/commands/secrets/delete/_logic.py +5 -0
- frogml_cli/commands/secrets/delete/ui.py +21 -0
- frogml_cli/commands/secrets/get/__init__.py +0 -0
- frogml_cli/commands/secrets/get/_logic.py +5 -0
- frogml_cli/commands/secrets/get/ui.py +17 -0
- frogml_cli/commands/secrets/secrets_commands_group.py +19 -0
- frogml_cli/commands/secrets/set/__init__.py +0 -0
- frogml_cli/commands/secrets/set/_logic.py +5 -0
- frogml_cli/commands/secrets/set/ui.py +16 -0
- frogml_cli/commands/ui_tools.py +18 -0
- frogml_cli/exceptions/__init__.py +14 -0
- frogml_cli/exceptions/frogml_command_exception.py +2 -0
- frogml_cli/exceptions/frogml_deploy_new_build_failed.py +5 -0
- frogml_cli/exceptions/frogml_resource_not_found.py +2 -0
- frogml_cli/inner/__init__.py +0 -0
- frogml_cli/inner/file_registry.py +98 -0
- frogml_cli/inner/tools/__init__.py +0 -0
- frogml_cli/inner/tools/cli_tools.py +179 -0
- frogml_cli/inner/tools/config_handler.py +29 -0
- frogml_cli/inner/tools/dataclasses_utils.py +21 -0
- frogml_cli/inner/tools/logger/__init__.py +3 -0
- frogml_cli/inner/tools/logger/logger.py +278 -0
- frogml_cli/inner/tools/logger/logging.yml +79 -0
- frogml_cli/inner/tools/tracking.py +47 -0
- frogml_cli/main.py +9 -0
- frogml_cli/tools/__init__.py +0 -0
- frogml_cli/tools/colors.py +13 -0
- frogml_cli/tools/const.py +3 -0
- frogml_cli/tools/files.py +63 -0
- frogml_cli/tools/log_handling.py +159 -0
- frogml_cli/tools/utils.py +45 -0
- frogml_cli-0.0.1.dist-info/METADATA +51 -0
- frogml_cli-0.0.1.dist-info/RECORD +287 -0
- frogml_cli-0.0.1.dist-info/WHEEL +4 -0
- frogml_cli-0.0.1.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,60 @@
|
|
1
|
+
import os
|
2
|
+
import shutil
|
3
|
+
from functools import wraps
|
4
|
+
from typing import List
|
5
|
+
|
6
|
+
from frogml.core.exceptions import QuietError
|
7
|
+
from frogml.core.inner.build_logic.interface.build_logger_interface import BuildLogger
|
8
|
+
from frogml.core.inner.build_logic.interface.step_inteface import Step
|
9
|
+
|
10
|
+
|
11
|
+
def step_exception_handler_decorator(step: Step):
|
12
|
+
execute_func = step.execute
|
13
|
+
|
14
|
+
@wraps(execute_func)
|
15
|
+
def inner_function(*args, **kwargs):
|
16
|
+
try:
|
17
|
+
execute_func(*args, **kwargs)
|
18
|
+
except BaseException as e:
|
19
|
+
if not isinstance(e, QuietError):
|
20
|
+
build_logger: BuildLogger = step.build_logger
|
21
|
+
build_logger.error(
|
22
|
+
"Build failed with Exception. See the stack trace above."
|
23
|
+
)
|
24
|
+
cleaning_up_after_build(step)
|
25
|
+
raise e
|
26
|
+
|
27
|
+
return inner_function
|
28
|
+
|
29
|
+
|
30
|
+
def build_failure_handler():
|
31
|
+
def _exception_handler(func):
|
32
|
+
@wraps(func)
|
33
|
+
def inner_function(*args, **kwargs):
|
34
|
+
try:
|
35
|
+
func(*args, **kwargs)
|
36
|
+
except BaseException as e:
|
37
|
+
if not isinstance(e, QuietError):
|
38
|
+
build_logger: BuildLogger = args[0].build_logger
|
39
|
+
build_logger.error(
|
40
|
+
"Build failed with Exception. See the stack trace above."
|
41
|
+
)
|
42
|
+
cleaning_up_after_build(args[0])
|
43
|
+
raise e
|
44
|
+
return inner_function
|
45
|
+
|
46
|
+
return _exception_handler
|
47
|
+
|
48
|
+
|
49
|
+
def cleaning_up_after_build(step: Step):
|
50
|
+
if os.getenv("QWAK_DEBUG") != "true":
|
51
|
+
step.build_logger.debug("Removing Qwak temp artifacts directory")
|
52
|
+
shutil.rmtree(step.context.host_temp_local_build_dir, ignore_errors=True)
|
53
|
+
|
54
|
+
|
55
|
+
def add_decorator_to_steps(phase_steps: List[Step]):
|
56
|
+
for step in phase_steps:
|
57
|
+
if not hasattr(step.execute, '__wrapped__'):
|
58
|
+
step_exception_handler_decorator(step)
|
59
|
+
|
60
|
+
return phase_steps
|
@@ -0,0 +1,27 @@
|
|
1
|
+
from logging import Logger
|
2
|
+
import time
|
3
|
+
from typing import List
|
4
|
+
from frogml._proto.qwak.builds.builds_pb2 import BuildStatus
|
5
|
+
from frogml.core.clients.build_orchestrator import BuildOrchestratorClient
|
6
|
+
|
7
|
+
|
8
|
+
def __get_current_status(build_id) -> BuildStatus:
|
9
|
+
return BuildOrchestratorClient().get_build(build_id).build.build_status
|
10
|
+
|
11
|
+
|
12
|
+
def __end_state_statuses() -> List[BuildStatus.ValueType]:
|
13
|
+
return [BuildStatus.FAILED, BuildStatus.SUCCESSFUL, BuildStatus.REMOTE_BUILD_CANCELLED, BuildStatus.REMOTE_BUILD_TIMED_OUT]
|
14
|
+
|
15
|
+
|
16
|
+
def wait_until_finished(build_id, log: Logger, pool_interval_seconds=10) -> None:
|
17
|
+
status = __get_current_status(build_id)
|
18
|
+
log.info(f"Waiting for build {build_id} to finish. Aborting this process will not stop the build!")
|
19
|
+
log.debug(f"Current status of build {build_id}: {BuildStatus.DESCRIPTOR.values_by_number[status].name}")
|
20
|
+
while status not in __end_state_statuses():
|
21
|
+
time.sleep(pool_interval_seconds)
|
22
|
+
status = __get_current_status(build_id)
|
23
|
+
log.debug(f"Current status of build {build_id}: {BuildStatus.DESCRIPTOR.values_by_number[status].name}")
|
24
|
+
|
25
|
+
|
26
|
+
def is_final_status_successful(build_id) -> bool:
|
27
|
+
return __get_current_status(build_id) == BuildStatus.SUCCESSFUL
|
@@ -0,0 +1,337 @@
|
|
1
|
+
import click
|
2
|
+
from frogml.core.inner.build_config.build_config_v1 import (
|
3
|
+
BuildConfigV1,
|
4
|
+
BuildProperties,
|
5
|
+
DockerConf,
|
6
|
+
ModelUri,
|
7
|
+
RemoteBuildResources,
|
8
|
+
)
|
9
|
+
from frogml.core.inner.build_logic.execute_build_pipeline import execute_build_pipeline
|
10
|
+
from frogml.core.inner.build_logic.run_handlers.programmatic_phase_run_handler import (
|
11
|
+
ProgrammaticPhaseRunHandler,
|
12
|
+
)
|
13
|
+
|
14
|
+
from frogml_cli.commands.models.build._logic.build_steps import create_pipeline
|
15
|
+
from frogml_cli.commands.models.build._logic.wait_until_finished import wait_until_finished, is_final_status_successful
|
16
|
+
from frogml_cli.commands.models.build._logic.client_logs.cli_phase_run_handler import (
|
17
|
+
CLIPhaseRunHandler,
|
18
|
+
)
|
19
|
+
from frogml_cli.commands.models.build._logic.client_logs.logger import get_build_logger
|
20
|
+
from frogml_cli.commands.models.build._logic.client_logs.utils import zip_logs
|
21
|
+
from frogml_cli.inner.tools.cli_tools import FrogMLCommand
|
22
|
+
from frogml_cli.inner.tools.config_handler import config_handler
|
23
|
+
from frogml_cli.tools.const import GPU_TYPES
|
24
|
+
|
25
|
+
|
26
|
+
@click.command("build", cls=FrogMLCommand)
|
27
|
+
@click.option(
|
28
|
+
"--model-id",
|
29
|
+
metavar="NAME",
|
30
|
+
required=False,
|
31
|
+
help="Model ID to assign the build for",
|
32
|
+
)
|
33
|
+
@click.option(
|
34
|
+
"--main-dir",
|
35
|
+
metavar="NAME",
|
36
|
+
help=f"Model main directory name, [Default: {ModelUri.main_dir}]",
|
37
|
+
)
|
38
|
+
@click.option(
|
39
|
+
"-P",
|
40
|
+
"--param-list",
|
41
|
+
required=False,
|
42
|
+
metavar="NAME=VALUE",
|
43
|
+
multiple=True,
|
44
|
+
help="A parameter for the build, of the form -P name=value. the params will be saved and can be viewed later",
|
45
|
+
)
|
46
|
+
@click.option(
|
47
|
+
"-E",
|
48
|
+
"--env-vars",
|
49
|
+
required=False,
|
50
|
+
metavar="NAME=VALUE",
|
51
|
+
multiple=True,
|
52
|
+
help="A parameter for the build, of the form -E name=value",
|
53
|
+
)
|
54
|
+
@click.option(
|
55
|
+
"-T",
|
56
|
+
"--tags",
|
57
|
+
required=False,
|
58
|
+
multiple=True,
|
59
|
+
help="A tag for the model build",
|
60
|
+
)
|
61
|
+
@click.option(
|
62
|
+
"--git-credentials",
|
63
|
+
required=False,
|
64
|
+
metavar="USERNAME:ACCESS_TOKEN",
|
65
|
+
help="Access credentials for private repositories listed in the python dependencies file",
|
66
|
+
)
|
67
|
+
@click.option(
|
68
|
+
"--git-branch",
|
69
|
+
metavar="NAME",
|
70
|
+
required=False,
|
71
|
+
help=f"Branch to use for git repo model code if defined."
|
72
|
+
f"\n[Default: {ModelUri.git_branch}]",
|
73
|
+
)
|
74
|
+
@click.option(
|
75
|
+
"--git-credentials-secret",
|
76
|
+
metavar="NAME",
|
77
|
+
required=False,
|
78
|
+
help="Predefined Frogml secret secret name, that contains access credentials to private repositories"
|
79
|
+
+ "Secrets should be of the form USERNAME:ACCESS_TOKEN. For info regarding defining Frogml Secrets using the"
|
80
|
+
+ "`frogml secret` command",
|
81
|
+
)
|
82
|
+
@click.option(
|
83
|
+
"--cpus",
|
84
|
+
metavar="NAME",
|
85
|
+
required=False,
|
86
|
+
help="Number of cpus to use on the remote build. [Default (If GPU not configured): 2] "
|
87
|
+
"(DO NOT CONFIGURE GPU AND CPU TOGETHER)",
|
88
|
+
type=click.FLOAT,
|
89
|
+
)
|
90
|
+
@click.option(
|
91
|
+
"--memory",
|
92
|
+
metavar="NAME",
|
93
|
+
required=False,
|
94
|
+
help="Memory to use on the remote build. [Default (If GPU not configured): 4Gi] "
|
95
|
+
"(DO NOT CONFIGURE GPU AND CPU TOGETHER)",
|
96
|
+
)
|
97
|
+
@click.option(
|
98
|
+
"--gpu-type",
|
99
|
+
metavar="NAME",
|
100
|
+
required=False,
|
101
|
+
help=f"Type of GPU to use on the remote build ({', '.join([x for x in GPU_TYPES])})."
|
102
|
+
f"\n[Default: {RemoteBuildResources.gpu_type}]"
|
103
|
+
"(DO NOT CONFIGURE GPU AND CPU TOGETHER)",
|
104
|
+
type=click.STRING,
|
105
|
+
)
|
106
|
+
@click.option(
|
107
|
+
"--gpu-amount",
|
108
|
+
metavar="NAME",
|
109
|
+
required=False,
|
110
|
+
type=int,
|
111
|
+
help=f"Amount of GPU's to use on the remote build."
|
112
|
+
f"\n[Default: {RemoteBuildResources.gpu_amount}] "
|
113
|
+
"(DO NOT CONFIGURE GPU AND CPU TOGETHER)",
|
114
|
+
)
|
115
|
+
@click.option(
|
116
|
+
"--gpu-compatible",
|
117
|
+
help=f"Whether to build an image that is compatible to be deployd on a GPU instance."
|
118
|
+
f"\n[Default: {BuildProperties.gpu_compatible}] ",
|
119
|
+
default=False,
|
120
|
+
is_flag=True,
|
121
|
+
)
|
122
|
+
@click.option(
|
123
|
+
"--iam-role-arn",
|
124
|
+
required=False,
|
125
|
+
type=str,
|
126
|
+
help="Custom IAM Role ARN for AWS based builds",
|
127
|
+
)
|
128
|
+
@click.option(
|
129
|
+
"--service-account-key-secret-name",
|
130
|
+
type=str,
|
131
|
+
help="Custom service account for GCP",
|
132
|
+
)
|
133
|
+
@click.option(
|
134
|
+
"--cache/--no-cache",
|
135
|
+
default=None,
|
136
|
+
help="Disable docker build cache. [Default: Cache enabled]",
|
137
|
+
)
|
138
|
+
@click.option(
|
139
|
+
"-v",
|
140
|
+
"--verbose",
|
141
|
+
count=True,
|
142
|
+
default=None,
|
143
|
+
help="Log verbosity level - v: INFO, vv: DEBUG [default: WARNING], Default ERROR",
|
144
|
+
)
|
145
|
+
@click.option(
|
146
|
+
"--base-image",
|
147
|
+
help="Used for customizing the docker container image built for train, build and deploy."
|
148
|
+
"Docker images should be based on Frogml images, The entrypoint or cmd of the docker "
|
149
|
+
"image should not be changed."
|
150
|
+
f"\n[Default: {DockerConf.base_image}]",
|
151
|
+
required=False,
|
152
|
+
)
|
153
|
+
@click.option(
|
154
|
+
"-f",
|
155
|
+
"--from-file",
|
156
|
+
help="Build by run_config file, Command arguments will overwrite any run_config.",
|
157
|
+
required=False,
|
158
|
+
type=click.Path(exists=True, resolve_path=True, dir_okay=False),
|
159
|
+
)
|
160
|
+
@click.option(
|
161
|
+
"--out-conf",
|
162
|
+
help="Extract models build conf from command arguments, the command will not run it wil only output valid yaml "
|
163
|
+
"structure",
|
164
|
+
default=False,
|
165
|
+
is_flag=True,
|
166
|
+
)
|
167
|
+
@click.option(
|
168
|
+
"--json-logs",
|
169
|
+
help="Output logs as json for easier parsing",
|
170
|
+
default=False,
|
171
|
+
is_flag=True,
|
172
|
+
)
|
173
|
+
@click.option(
|
174
|
+
"--programmatic",
|
175
|
+
help="Run the _logic without the UI and receive the build id and any exception as return values",
|
176
|
+
default=False,
|
177
|
+
is_flag=True,
|
178
|
+
)
|
179
|
+
@click.option(
|
180
|
+
"--validate-build-artifact/--no-validate-build-artifact",
|
181
|
+
help="Skip validate build artifact step",
|
182
|
+
default=None,
|
183
|
+
)
|
184
|
+
@click.option(
|
185
|
+
"--tests/--no-tests",
|
186
|
+
help="Skip tests step",
|
187
|
+
default=None,
|
188
|
+
)
|
189
|
+
@click.option(
|
190
|
+
"--dependency-file-path",
|
191
|
+
help="Custom dependency file path",
|
192
|
+
default=None,
|
193
|
+
)
|
194
|
+
@click.option(
|
195
|
+
"--validate-build-artifact-timeout",
|
196
|
+
help="Timeout in seconds for the validation step",
|
197
|
+
default=120,
|
198
|
+
)
|
199
|
+
@click.option(
|
200
|
+
"--dependency-required-folders",
|
201
|
+
help="Folder to be copied into the build. In order to copy several folders, use this flag several times",
|
202
|
+
default=None,
|
203
|
+
required=False,
|
204
|
+
multiple=True,
|
205
|
+
)
|
206
|
+
@click.option(
|
207
|
+
"--deploy",
|
208
|
+
help="Whether you want to deploy the build if it finishes successfully. "
|
209
|
+
"Choosing this will follow the build process in the terminal and will trigger a deployment when the "
|
210
|
+
"build finishes.",
|
211
|
+
default=False,
|
212
|
+
is_flag=True,
|
213
|
+
)
|
214
|
+
@click.option(
|
215
|
+
"--instance",
|
216
|
+
required=False,
|
217
|
+
type=str,
|
218
|
+
help="The instance size to build on - 'small', 'medium', 'large', etc...",
|
219
|
+
default=None,
|
220
|
+
)
|
221
|
+
@click.option(
|
222
|
+
"--deployment-instance",
|
223
|
+
required=False,
|
224
|
+
type=str,
|
225
|
+
help="The instance size to deploy on - 'small', 'medium', 'large', etc...",
|
226
|
+
default=None,
|
227
|
+
)
|
228
|
+
@click.option(
|
229
|
+
"--purchase-option",
|
230
|
+
required=False,
|
231
|
+
type=str,
|
232
|
+
help="The type of the instance to build on - 'ondemand' or 'spot'",
|
233
|
+
default=None,
|
234
|
+
)
|
235
|
+
@click.option(
|
236
|
+
"--id-only",
|
237
|
+
help="Receiving only the build id and any exception as return values (Depends on "
|
238
|
+
"--programmatic in order to avoid UI output too)",
|
239
|
+
default=False,
|
240
|
+
is_flag=True,
|
241
|
+
)
|
242
|
+
@click.option(
|
243
|
+
"--sync",
|
244
|
+
help="Waits until the build is finished (successfully or not) and return the build status",
|
245
|
+
default=False,
|
246
|
+
is_flag=True,
|
247
|
+
)
|
248
|
+
@click.option(
|
249
|
+
"--git-secret-ssh",
|
250
|
+
metavar="NAME",
|
251
|
+
required=False,
|
252
|
+
help="[REMOTE BUILD] Predefined Frogml ssh secret name, that contains access credentials to private repositories"
|
253
|
+
+ "secret ssh key should contain the private ssh key."
|
254
|
+
+ "`frogml secret` command",
|
255
|
+
)
|
256
|
+
@click.option(
|
257
|
+
"--push/--no-push",
|
258
|
+
help="Whether to push the build image to the registry (default is True)",
|
259
|
+
default=True,
|
260
|
+
is_flag=True,
|
261
|
+
)
|
262
|
+
@click.option(
|
263
|
+
"--provision-instance-timeout",
|
264
|
+
help="Timeout in minutes for the provision instance step",
|
265
|
+
default=120,
|
266
|
+
)
|
267
|
+
@click.option(
|
268
|
+
"-N",
|
269
|
+
"--name",
|
270
|
+
"build_name",
|
271
|
+
required=False,
|
272
|
+
help="The build's name",
|
273
|
+
)
|
274
|
+
@click.argument("uri", required=False)
|
275
|
+
def models_build(**kwargs):
|
276
|
+
return build(**kwargs)
|
277
|
+
|
278
|
+
|
279
|
+
def build(
|
280
|
+
from_file: str,
|
281
|
+
out_conf: bool,
|
282
|
+
json_logs: bool,
|
283
|
+
programmatic: bool,
|
284
|
+
**kwargs,
|
285
|
+
):
|
286
|
+
# If FROGML_DEBUG=true is set then the artifacts will not be deleted, all intermediate files located in ~/.frogml/builds
|
287
|
+
# Including all intermediate images
|
288
|
+
config: BuildConfigV1 = config_handler(
|
289
|
+
config=BuildConfigV1,
|
290
|
+
from_file=from_file,
|
291
|
+
out_conf=out_conf,
|
292
|
+
**kwargs,
|
293
|
+
)
|
294
|
+
if out_conf:
|
295
|
+
return
|
296
|
+
else:
|
297
|
+
id_only = kwargs.get("id_only")
|
298
|
+
is_sync = kwargs.get("sync")
|
299
|
+
pipeline, success_msg = create_pipeline(config)
|
300
|
+
with get_build_logger(config=config, json_logs=json_logs) as (
|
301
|
+
logger,
|
302
|
+
log_path,
|
303
|
+
):
|
304
|
+
if programmatic:
|
305
|
+
build_runner = ProgrammaticPhaseRunHandler(
|
306
|
+
logger, config.verbose, json_logs
|
307
|
+
)
|
308
|
+
else:
|
309
|
+
build_runner = CLIPhaseRunHandler(
|
310
|
+
logger, log_path, config.verbose, json_logs
|
311
|
+
)
|
312
|
+
|
313
|
+
execute_build_pipeline(
|
314
|
+
pipeline,
|
315
|
+
build_runner,
|
316
|
+
)
|
317
|
+
|
318
|
+
if is_sync:
|
319
|
+
wait_until_finished(pipeline.context.build_id, logger)
|
320
|
+
if not is_final_status_successful(pipeline.context.build_id):
|
321
|
+
click.echo(f"Build {pipeline.context.build_id} failed")
|
322
|
+
exit(1)
|
323
|
+
|
324
|
+
if id_only:
|
325
|
+
print(pipeline.context.build_id)
|
326
|
+
else:
|
327
|
+
print(
|
328
|
+
success_msg.format(
|
329
|
+
base_url=pipeline.context.platform_url,
|
330
|
+
build_id=pipeline.context.build_id,
|
331
|
+
model_id=pipeline.context.model_id,
|
332
|
+
project_uuid=pipeline.context.project_uuid,
|
333
|
+
)
|
334
|
+
)
|
335
|
+
zip_logs(log_path=log_path, build_id=pipeline.context.build_id)
|
336
|
+
|
337
|
+
return pipeline.context.build_id
|
File without changes
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import click
|
2
|
+
|
3
|
+
from frogml_cli.commands.models.builds.cancel.ui import cancel_build
|
4
|
+
from frogml_cli.commands.models.builds.logs.ui import build_logs
|
5
|
+
from frogml_cli.commands.models.builds.status.ui import get_build_status
|
6
|
+
|
7
|
+
|
8
|
+
@click.group(name="builds", help="Ongoing builds")
|
9
|
+
def builds_commands_group():
|
10
|
+
# Click commands group injection
|
11
|
+
pass
|
12
|
+
|
13
|
+
|
14
|
+
builds_commands_group.add_command(cancel_build)
|
15
|
+
builds_commands_group.add_command(get_build_status)
|
16
|
+
builds_commands_group.add_command(build_logs)
|
File without changes
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import click
|
2
|
+
from frogml.core.tools.logger.logger import get_frogml_logger
|
3
|
+
|
4
|
+
from frogml_cli.commands.models.builds.cancel._logic import execute_cancel_build
|
5
|
+
from frogml_cli.inner.tools.cli_tools import FrogMLCommand
|
6
|
+
|
7
|
+
logger = get_frogml_logger()
|
8
|
+
|
9
|
+
|
10
|
+
@click.command("cancel", cls=FrogMLCommand)
|
11
|
+
@click.argument("build_id")
|
12
|
+
def cancel_build(build_id, **kwargs):
|
13
|
+
logger.info(f"Attempting to cancel remote build with build id [{build_id}]")
|
14
|
+
execute_cancel_build(build_id=build_id)
|
15
|
+
logger.info("Successfully canceled remote build")
|
File without changes
|
@@ -0,0 +1,35 @@
|
|
1
|
+
import click
|
2
|
+
|
3
|
+
from frogml_cli.inner.tools.cli_tools import FrogMLCommand
|
4
|
+
from frogml_cli.tools.log_handling import FrogmlLogHandling
|
5
|
+
|
6
|
+
|
7
|
+
@click.command("logs", cls=FrogMLCommand)
|
8
|
+
@click.option("-f", "--follow", is_flag=True, default=False, help="Follow log tail")
|
9
|
+
@click.option(
|
10
|
+
"-b", "--build-id", required=True, help="Runtime model Build ID to show logs of"
|
11
|
+
)
|
12
|
+
@click.option(
|
13
|
+
"-s",
|
14
|
+
"--since",
|
15
|
+
required=False,
|
16
|
+
metavar="X [TYPE] ago",
|
17
|
+
help=f"Get logs from X1 [type] X2 [type]... Xn [type] ago. "
|
18
|
+
f"(x = INT; type = {FrogmlLogHandling.TIME_UNITS}) i.e. [1 day 2 hours ago]",
|
19
|
+
)
|
20
|
+
@click.option(
|
21
|
+
"-n",
|
22
|
+
"--number-of-results",
|
23
|
+
required=False,
|
24
|
+
type=int,
|
25
|
+
help="Maximum number of results per query",
|
26
|
+
)
|
27
|
+
@click.option(
|
28
|
+
"-g", "--grep", required=False, help="Filter by log content contains [expression]"
|
29
|
+
)
|
30
|
+
def build_logs(
|
31
|
+
follow=True, build_id=None, since=None, number_of_results=None, grep=None, **kwargs
|
32
|
+
):
|
33
|
+
FrogmlLogHandling().get_logs(
|
34
|
+
follow, since, number_of_results, grep, {"build_id": build_id}, "build"
|
35
|
+
)
|
File without changes
|
@@ -0,0 +1,6 @@
|
|
1
|
+
from frogml._proto.qwak.builds.builds_pb2 import BuildStatus
|
2
|
+
from frogml.core.clients.build_orchestrator import BuildOrchestratorClient
|
3
|
+
|
4
|
+
|
5
|
+
def execute_get_build_status(build_id) -> BuildStatus:
|
6
|
+
return BuildOrchestratorClient().get_build(build_id).build.build_status
|
@@ -0,0 +1,39 @@
|
|
1
|
+
import json
|
2
|
+
|
3
|
+
import click
|
4
|
+
from frogml._proto.qwak.builds.builds_pb2 import BuildStatus
|
5
|
+
from frogml.core.tools.logger.logger import get_frogml_logger
|
6
|
+
|
7
|
+
from frogml_cli.commands.models.builds.status._logic import execute_get_build_status
|
8
|
+
from frogml_cli.inner.tools.cli_tools import FrogMLCommand
|
9
|
+
|
10
|
+
logger = get_frogml_logger()
|
11
|
+
|
12
|
+
|
13
|
+
@click.command("status", cls=FrogMLCommand)
|
14
|
+
@click.argument("build_id")
|
15
|
+
@click.option(
|
16
|
+
"--format",
|
17
|
+
default="text",
|
18
|
+
show_default=True,
|
19
|
+
type=click.Choice(["text", "json"], case_sensitive=True),
|
20
|
+
metavar="FORMAT",
|
21
|
+
required=False,
|
22
|
+
help="The formatting style for commands output (choose from text, json)",
|
23
|
+
)
|
24
|
+
def get_build_status(build_id, format, **kwargs):
|
25
|
+
if format == "text":
|
26
|
+
logger.info(f"Getting build status for build id [{build_id}]")
|
27
|
+
build_status = execute_get_build_status(build_id)
|
28
|
+
if format == "text":
|
29
|
+
logger.info(f"Build status: {BuildStatus.Name(build_status)}")
|
30
|
+
elif format == "json":
|
31
|
+
print(
|
32
|
+
json.dumps(
|
33
|
+
{
|
34
|
+
"build_id": build_id,
|
35
|
+
"build_status": BuildStatus.Name(build_status),
|
36
|
+
}
|
37
|
+
)
|
38
|
+
)
|
39
|
+
return BuildStatus.Name(build_status)
|
File without changes
|
@@ -0,0 +1,40 @@
|
|
1
|
+
import logging
|
2
|
+
|
3
|
+
from frogml._proto.qwak.model_group.model_group_pb2 import ModelGroupBriefInfoResponse
|
4
|
+
from frogml._proto.qwak.models.models_pb2 import CreateModelResponse
|
5
|
+
from frogml.core.clients.model_group_management import ModelGroupManagementClient
|
6
|
+
from frogml.core.clients.model_management import ModelsManagementClient
|
7
|
+
from frogml.core.exceptions import FrogmlException
|
8
|
+
|
9
|
+
from frogml_cli.exceptions import FrogmlCommandException
|
10
|
+
|
11
|
+
logger = logging.getLogger(__name__)
|
12
|
+
|
13
|
+
|
14
|
+
def execute_model_create(
|
15
|
+
model_name: str,
|
16
|
+
model_description: str,
|
17
|
+
jfrog_project_key: str,
|
18
|
+
) -> CreateModelResponse:
|
19
|
+
if not jfrog_project_key:
|
20
|
+
raise FrogmlCommandException("You must supply project key")
|
21
|
+
try:
|
22
|
+
response: ModelGroupBriefInfoResponse = (
|
23
|
+
ModelGroupManagementClient().create_if_not_exists_model_group(
|
24
|
+
project_key=jfrog_project_key
|
25
|
+
)
|
26
|
+
)
|
27
|
+
logger.info(
|
28
|
+
"Retrieved model group id %s that associated with project %s",
|
29
|
+
response.model_group_id,
|
30
|
+
jfrog_project_key,
|
31
|
+
)
|
32
|
+
return ModelsManagementClient().create_model(
|
33
|
+
project_id=response.model_group_id,
|
34
|
+
model_name=model_name,
|
35
|
+
model_description=model_description,
|
36
|
+
jfrog_project_key=jfrog_project_key,
|
37
|
+
)
|
38
|
+
except FrogmlException as e:
|
39
|
+
logger.error("Error occurred during model creation due to %s", e.message)
|
40
|
+
raise FrogmlCommandException(e)
|
@@ -0,0 +1,46 @@
|
|
1
|
+
import click
|
2
|
+
|
3
|
+
from frogml_cli.commands.models.create._logic import execute_model_create
|
4
|
+
from frogml_cli.commands.ui_tools import output_as_json
|
5
|
+
from frogml_cli.inner.tools.cli_tools import FrogMLCommand
|
6
|
+
from frogml_cli.tools.colors import Color
|
7
|
+
|
8
|
+
|
9
|
+
@click.command("create", cls=FrogMLCommand)
|
10
|
+
@click.argument("name", metavar="name", required=True)
|
11
|
+
@click.option(
|
12
|
+
"--project-key",
|
13
|
+
metavar="ID",
|
14
|
+
required=False,
|
15
|
+
help="An existing jfrog project key",
|
16
|
+
)
|
17
|
+
@click.option(
|
18
|
+
"--description",
|
19
|
+
metavar="DESCRIPTION",
|
20
|
+
required=False,
|
21
|
+
help="Model description",
|
22
|
+
)
|
23
|
+
@click.option(
|
24
|
+
"--format",
|
25
|
+
default="text",
|
26
|
+
show_default=True,
|
27
|
+
type=click.Choice(["text", "json"], case_sensitive=True),
|
28
|
+
metavar="FORMAT",
|
29
|
+
required=False,
|
30
|
+
help="The formatting style for commands output (choose from text, json)",
|
31
|
+
)
|
32
|
+
def model_create(
|
33
|
+
name,
|
34
|
+
project_key: str,
|
35
|
+
description,
|
36
|
+
format,
|
37
|
+
**kwargs,
|
38
|
+
):
|
39
|
+
try:
|
40
|
+
response = execute_model_create(name, description, project_key)
|
41
|
+
if format == "json":
|
42
|
+
output_as_json(response)
|
43
|
+
else:
|
44
|
+
print(f"Model created\nmodel id : {response.model_id}")
|
45
|
+
except Exception as e:
|
46
|
+
print(f"{Color.RED}Error creating model: {e}{Color.RED}")
|
File without changes
|
@@ -0,0 +1,18 @@
|
|
1
|
+
from frogml._proto.qwak.projects.projects_pb2 import GetProjectResponse
|
2
|
+
from frogml.core.clients.model_management import ModelsManagementClient
|
3
|
+
from frogml.core.clients.project.client import ProjectsManagementClient
|
4
|
+
from frogml.core.exceptions import FrogmlException
|
5
|
+
|
6
|
+
|
7
|
+
def execute_model_delete(project_key: str, model_id: str):
|
8
|
+
project_response: GetProjectResponse = ProjectsManagementClient().get_project(
|
9
|
+
project_name=project_key
|
10
|
+
)
|
11
|
+
is_model_exists: bool = any(
|
12
|
+
m.model_id == model_id for m in project_response.project.models
|
13
|
+
)
|
14
|
+
if not is_model_exists:
|
15
|
+
raise FrogmlException(f"No such model {model_id} for project {project_key}")
|
16
|
+
|
17
|
+
project_id: str = project_response.project.spec.project_id
|
18
|
+
return ModelsManagementClient().delete_model(project_id, model_id)
|