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,179 @@
|
|
1
|
+
import functools
|
2
|
+
import time
|
3
|
+
import warnings
|
4
|
+
from collections import namedtuple
|
5
|
+
from typing import Any, Callable, Dict, List, Tuple, Union
|
6
|
+
|
7
|
+
import click
|
8
|
+
from click import Context, OptionParser
|
9
|
+
from frogml.core.exceptions import FrogmlException
|
10
|
+
from frogml.core.inner.di_configuration import UserAccountConfiguration
|
11
|
+
|
12
|
+
from frogml_cli.inner.tools.tracking import log_event
|
13
|
+
|
14
|
+
|
15
|
+
def get_user_identifiers(account: UserAccountConfiguration):
|
16
|
+
try:
|
17
|
+
user_id = account.get_user_config().token
|
18
|
+
identifier_cls = namedtuple("Identifier", ["user_id"])
|
19
|
+
return identifier_cls(user_id)
|
20
|
+
|
21
|
+
except FrogmlException:
|
22
|
+
# User might not be registered or have a valid API key
|
23
|
+
return None
|
24
|
+
|
25
|
+
|
26
|
+
def usage_statistics_wrapper(func: Callable):
|
27
|
+
@functools.wraps(func)
|
28
|
+
def wrapper(*args, **kwargs):
|
29
|
+
ctx = click.get_current_context()
|
30
|
+
start_time = time.time()
|
31
|
+
|
32
|
+
account = UserAccountConfiguration()
|
33
|
+
user_identifiers = get_user_identifiers(account)
|
34
|
+
|
35
|
+
# If we could not get user identifiers for some reason (for example - user not logged in) - do not track
|
36
|
+
if not user_identifiers:
|
37
|
+
return func(*args, **kwargs)
|
38
|
+
|
39
|
+
event_properties = {
|
40
|
+
"command_group": ctx.command_path,
|
41
|
+
"commands": ctx.command.name,
|
42
|
+
"duration": time.time() - start_time,
|
43
|
+
}
|
44
|
+
try:
|
45
|
+
return_value = func(*args, **kwargs)
|
46
|
+
|
47
|
+
event_properties["response"] = return_value
|
48
|
+
event_properties["status"] = 0
|
49
|
+
log_event(
|
50
|
+
event_properties,
|
51
|
+
user_id=user_identifiers.user_id,
|
52
|
+
)
|
53
|
+
|
54
|
+
return return_value
|
55
|
+
|
56
|
+
except BaseException as e:
|
57
|
+
command_status = 1
|
58
|
+
if type(e) == KeyboardInterrupt:
|
59
|
+
command_status = 1
|
60
|
+
|
61
|
+
event_properties["error_type"] = type(e).__name__
|
62
|
+
event_properties["error_message"] = str(e)
|
63
|
+
event_properties["status"] = command_status
|
64
|
+
|
65
|
+
log_event(
|
66
|
+
event_properties,
|
67
|
+
user_id=user_identifiers.user_id,
|
68
|
+
)
|
69
|
+
raise
|
70
|
+
|
71
|
+
return wrapper
|
72
|
+
|
73
|
+
|
74
|
+
class DeprecatedOption(click.Option):
|
75
|
+
def __init__(self, *args, **kwargs):
|
76
|
+
self.deprecated = kwargs.pop("deprecated", ())
|
77
|
+
self.preferred = kwargs.pop("preferred", args[0][-1])
|
78
|
+
super(DeprecatedOption, self).__init__(*args, **kwargs)
|
79
|
+
|
80
|
+
|
81
|
+
class FrogMLCommand(click.Command):
|
82
|
+
def __init__(self, *args, **kwargs):
|
83
|
+
super().__init__(*args, **kwargs)
|
84
|
+
|
85
|
+
def make_parser(self, ctx: Context) -> OptionParser:
|
86
|
+
parser = super(FrogMLCommand, self).make_parser(ctx)
|
87
|
+
|
88
|
+
# get the parser options
|
89
|
+
options = set(parser._short_opt.values())
|
90
|
+
options |= set(parser._long_opt.values())
|
91
|
+
|
92
|
+
for option in options:
|
93
|
+
if not isinstance(option.obj, DeprecatedOption):
|
94
|
+
continue
|
95
|
+
|
96
|
+
def make_process(an_option):
|
97
|
+
"""Construct a closure to the parser option processor"""
|
98
|
+
|
99
|
+
orig_process = an_option.process
|
100
|
+
deprecated = getattr(an_option.obj, "deprecated", None)
|
101
|
+
preferred = getattr(an_option.obj, "preferred", None)
|
102
|
+
|
103
|
+
if not deprecated:
|
104
|
+
f"Expected `deprecated` value for `{an_option.obj.name}`"
|
105
|
+
|
106
|
+
def process(value, state):
|
107
|
+
"""The function above us on the stack used 'opt' to
|
108
|
+
pick option from a dict, see if it is deprecated"""
|
109
|
+
|
110
|
+
# reach up the stack and get 'opt'
|
111
|
+
import inspect
|
112
|
+
|
113
|
+
frame = inspect.currentframe()
|
114
|
+
try:
|
115
|
+
opt = frame.f_back.f_locals.get("opt")
|
116
|
+
finally:
|
117
|
+
del frame
|
118
|
+
|
119
|
+
if opt in deprecated:
|
120
|
+
warnings.warn(
|
121
|
+
f"{opt} has been deprecated, use {preferred}."
|
122
|
+
f" {opt} will be removed in future releases.",
|
123
|
+
DeprecationWarning,
|
124
|
+
)
|
125
|
+
|
126
|
+
return orig_process(value, state)
|
127
|
+
|
128
|
+
return process
|
129
|
+
|
130
|
+
option.process = make_process(option)
|
131
|
+
|
132
|
+
return parser
|
133
|
+
|
134
|
+
@usage_statistics_wrapper
|
135
|
+
def invoke(self, ctx: click.Context) -> Any:
|
136
|
+
return super().invoke(ctx)
|
137
|
+
|
138
|
+
|
139
|
+
def ask_yesno(
|
140
|
+
question: str, force: bool, print_callback: Callable[[str], None] = print
|
141
|
+
) -> bool:
|
142
|
+
"""
|
143
|
+
Helper to get yes / no answer from user.
|
144
|
+
|
145
|
+
Args:
|
146
|
+
question: yes/no question to show the user
|
147
|
+
force: automatically returns True if force is True
|
148
|
+
print_callback: function to use for printing
|
149
|
+
|
150
|
+
Returns:
|
151
|
+
True/False by user input (unless forced and then always True)
|
152
|
+
"""
|
153
|
+
|
154
|
+
print_callback(f"{question}")
|
155
|
+
if force:
|
156
|
+
print_callback("Forced yes")
|
157
|
+
return True
|
158
|
+
return click.confirm("continue?")
|
159
|
+
|
160
|
+
|
161
|
+
def dictify_params(env_vars: Union[Dict[str, str], List[str], Tuple[str]]):
|
162
|
+
result = dict()
|
163
|
+
|
164
|
+
if env_vars is None:
|
165
|
+
return result
|
166
|
+
|
167
|
+
if isinstance(env_vars, dict):
|
168
|
+
return env_vars
|
169
|
+
|
170
|
+
if isinstance(env_vars, (list, tuple)):
|
171
|
+
for env_var in env_vars:
|
172
|
+
if "=" not in env_var:
|
173
|
+
raise FrogmlException(
|
174
|
+
f'The environment variable definition passed {env_var} is invalid. Format is "KEY=VALUE"'
|
175
|
+
)
|
176
|
+
split_param = env_var.split("=")
|
177
|
+
result[split_param[0]] = split_param[1]
|
178
|
+
|
179
|
+
return result
|
@@ -0,0 +1,29 @@
|
|
1
|
+
from typing import Any, Tuple, Union
|
2
|
+
|
3
|
+
from frogml.core.clients.build_orchestrator import BuildOrchestratorClient
|
4
|
+
from frogml.core.clients.instance_template.client import (
|
5
|
+
InstanceTemplateManagementClient,
|
6
|
+
)
|
7
|
+
from frogml.core.inner.build_config.build_config_v1 import BuildConfigV1
|
8
|
+
from frogml.core.inner.tool.run_config import FrogmlConfigBase, YamlConfigMixin
|
9
|
+
|
10
|
+
|
11
|
+
def config_handler(
|
12
|
+
config: Union[FrogmlConfigBase, YamlConfigMixin, Any],
|
13
|
+
from_file: str,
|
14
|
+
out_conf: bool,
|
15
|
+
sections: Tuple[str, ...] = (),
|
16
|
+
**kwargs,
|
17
|
+
) -> Any:
|
18
|
+
conf: Union[FrogmlConfigBase, YamlConfigMixin] = config.from_yaml(from_file)
|
19
|
+
conf.merge_cli_argument(sections=sections, **kwargs)
|
20
|
+
|
21
|
+
if isinstance(conf, BuildConfigV1):
|
22
|
+
conf.fetch_base_docker_image_name(
|
23
|
+
BuildOrchestratorClient(), InstanceTemplateManagementClient()
|
24
|
+
)
|
25
|
+
|
26
|
+
if out_conf:
|
27
|
+
print(conf.to_yaml())
|
28
|
+
|
29
|
+
return conf
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import dataclasses
|
2
|
+
from typing import Any, Dict, List, Type, Union
|
3
|
+
|
4
|
+
|
5
|
+
def create_dataclass_instance(dataclass_type: Type, input_dict: Dict[str, Any]) -> Any:
|
6
|
+
fields = {f.name: f.type for f in dataclasses.fields(dataclass_type)}
|
7
|
+
|
8
|
+
def construct_dataclass(
|
9
|
+
dc_type: Union[Type, List], value: Any
|
10
|
+
) -> Union[Type, List]:
|
11
|
+
if dataclasses.is_dataclass(dc_type):
|
12
|
+
return create_dataclass_instance(dc_type, value)
|
13
|
+
elif getattr(dc_type, "__origin__", None) is list: # This is a List
|
14
|
+
element_type = dc_type.__args__[0]
|
15
|
+
return [construct_dataclass(element_type, v) for v in value]
|
16
|
+
else:
|
17
|
+
return value
|
18
|
+
|
19
|
+
return dataclass_type(
|
20
|
+
**{k: construct_dataclass(fields[k], v) for k, v in input_dict.items()}
|
21
|
+
)
|
@@ -0,0 +1,278 @@
|
|
1
|
+
import logging
|
2
|
+
import logging.config
|
3
|
+
import os
|
4
|
+
from logging.handlers import RotatingFileHandler
|
5
|
+
from pathlib import Path
|
6
|
+
from typing import Optional
|
7
|
+
|
8
|
+
import yaml
|
9
|
+
from frogml.core.exceptions import FrogmlException
|
10
|
+
|
11
|
+
DEFAULT_LOGGER_NAME = "frogml"
|
12
|
+
REMOTE_LOGGER_NAME = "frogml_remote"
|
13
|
+
MODEL_LOGGER_NAME = "frogml_model"
|
14
|
+
FEATURE_STORE_LOGGER_NAME = "feature_store"
|
15
|
+
BUILD_LOCAL_LOGGER_NAME = "build_local"
|
16
|
+
DOCKER_INTERNAL_LOGGER_NAME = "docker_internal"
|
17
|
+
|
18
|
+
ENVIRON_LOGGER_TYPE = "LOGGER_TYPE"
|
19
|
+
|
20
|
+
BUILD_LOCAL_FILE_HANDLER_NAME = "build_log_file_handler"
|
21
|
+
FILE_HANDLER_NAME = "file_handler"
|
22
|
+
CONSOLE_HANDLER_NAME = "console"
|
23
|
+
REMOTE_CONSOLE_HANDLER_NAME = "remote_console"
|
24
|
+
|
25
|
+
DEFINED_LOGGER_NAMES = {
|
26
|
+
DEFAULT_LOGGER_NAME,
|
27
|
+
REMOTE_LOGGER_NAME,
|
28
|
+
MODEL_LOGGER_NAME,
|
29
|
+
FEATURE_STORE_LOGGER_NAME,
|
30
|
+
BUILD_LOCAL_LOGGER_NAME,
|
31
|
+
DOCKER_INTERNAL_LOGGER_NAME,
|
32
|
+
}
|
33
|
+
|
34
|
+
VERBOSITY_LEVEL_MAPPING = {0: logging.CRITICAL, 1: logging.INFO, 2: logging.DEBUG}
|
35
|
+
REVERSED_VERBOSITY_LEVEL_MAPPING = {
|
36
|
+
value: key for key, value in VERBOSITY_LEVEL_MAPPING.items()
|
37
|
+
}
|
38
|
+
|
39
|
+
AIRFLOW_ENV_FLAG = "AIRFLOW__LOGGING__REMOTE_LOGGING"
|
40
|
+
|
41
|
+
|
42
|
+
def setup_frogml_logger(
|
43
|
+
default_level: int = logging.INFO,
|
44
|
+
logger_name_handler_addition: str = None,
|
45
|
+
disable_existing_loggers: bool = False,
|
46
|
+
):
|
47
|
+
"""Setup frogml logger:
|
48
|
+
1. Rotating file in $HOME/.frogml/log/sdk.log (10MB * 5 files) (DEBUG level)
|
49
|
+
2. Stdout logger with colored logs. (INFO level)
|
50
|
+
|
51
|
+
Args:
|
52
|
+
default_level: Default logging level in case of failure
|
53
|
+
logger_name_handler_addition:
|
54
|
+
Logger name which the handlers of will be appended to all loggers which have handlers
|
55
|
+
Overriding stdout stream handler if exists
|
56
|
+
disable_existing_loggers: disables all existing loggers
|
57
|
+
|
58
|
+
Raises:
|
59
|
+
FrogmlException: If loading logging.yml fails or the preparation of the logging environment raises an exceptions
|
60
|
+
|
61
|
+
Notes:
|
62
|
+
1. https://docs.python.org/3/library/logging.html#logging-levels
|
63
|
+
"""
|
64
|
+
|
65
|
+
config_file = Path(__file__).parent / "logging.yml"
|
66
|
+
if config_file.exists() and not non_frogml_logger_enabled():
|
67
|
+
with config_file.open(mode="rt") as f:
|
68
|
+
try:
|
69
|
+
# Creating log directory
|
70
|
+
log_path = Path(__get_config_folder())
|
71
|
+
log_path.mkdir(parents=True, exist_ok=True)
|
72
|
+
# Load logger configuration
|
73
|
+
config = yaml.safe_load(f.read())
|
74
|
+
config["handlers"][FILE_HANDLER_NAME]["filename"] = str(
|
75
|
+
log_path / "sdk.log"
|
76
|
+
)
|
77
|
+
config["handlers"][BUILD_LOCAL_FILE_HANDLER_NAME]["filename"] = str(
|
78
|
+
log_path / "sdk.log"
|
79
|
+
)
|
80
|
+
config["disable_existing_loggers"] = disable_existing_loggers
|
81
|
+
|
82
|
+
logging.config.dictConfig(config)
|
83
|
+
|
84
|
+
if logger_name_handler_addition:
|
85
|
+
if (
|
86
|
+
logger_name_handler_addition
|
87
|
+
in logging.Logger.manager.loggerDict
|
88
|
+
):
|
89
|
+
_add_logger_handlers(logger_name_handler_addition)
|
90
|
+
else:
|
91
|
+
print(
|
92
|
+
"Tried to set orphan loggers handlers with a non-existing logger name handlers'"
|
93
|
+
)
|
94
|
+
|
95
|
+
except Exception as e:
|
96
|
+
raise FrogmlException(
|
97
|
+
f"Error in Logging Configuration. Error message: {e}"
|
98
|
+
)
|
99
|
+
else:
|
100
|
+
logging.basicConfig(level=default_level)
|
101
|
+
print("Failed to load configuration file. Using default configs")
|
102
|
+
|
103
|
+
|
104
|
+
def __get_config_folder() -> str:
|
105
|
+
frogml_home_dir: str = (
|
106
|
+
os.getenv("FROGML_HOME")
|
107
|
+
if os.getenv("FROGML_HOME") is not None
|
108
|
+
else f"{str(Path.home())}"
|
109
|
+
)
|
110
|
+
|
111
|
+
return f"{frogml_home_dir}/.frogml"
|
112
|
+
|
113
|
+
|
114
|
+
def _add_logger_handlers(logger_name):
|
115
|
+
"""
|
116
|
+
Add a specific logger handlers to all loggers
|
117
|
+
Override loggers StreamHandler handlers if the input logger has a StreamHandler
|
118
|
+
|
119
|
+
Args:
|
120
|
+
logger_name: logger name which consists of the handlers we wish to set
|
121
|
+
"""
|
122
|
+
|
123
|
+
logger_handlers = logging.getLogger(logger_name).handlers
|
124
|
+
base_contains_stdout = any(
|
125
|
+
[
|
126
|
+
handler
|
127
|
+
for handler in logger_handlers
|
128
|
+
if type(handler) is logging.StreamHandler
|
129
|
+
]
|
130
|
+
)
|
131
|
+
|
132
|
+
for logger in [
|
133
|
+
logger
|
134
|
+
for logger in logging.Logger.manager.loggerDict.values()
|
135
|
+
if not isinstance(logger, logging.PlaceHolder)
|
136
|
+
]:
|
137
|
+
if logger.handlers:
|
138
|
+
logger.handlers = [
|
139
|
+
handler
|
140
|
+
for handler in logger.handlers
|
141
|
+
if base_contains_stdout and type(handler) is not logging.StreamHandler
|
142
|
+
] + logger_handlers
|
143
|
+
|
144
|
+
|
145
|
+
def get_frogml_logger(
|
146
|
+
logger_name: Optional[str] = None, fallback_logger_name: Optional[str] = None
|
147
|
+
) -> logging.Logger:
|
148
|
+
"""Get frogml logger (Singleton)
|
149
|
+
|
150
|
+
Returns:
|
151
|
+
logging.Logger: Frogml logger.
|
152
|
+
"""
|
153
|
+
if not logger_name:
|
154
|
+
logger_name = get_frogml_logger_name(fallback_logger_name)
|
155
|
+
|
156
|
+
if (logger_name not in DEFINED_LOGGER_NAMES) and not non_frogml_logger_enabled:
|
157
|
+
print("Failed to get requested logger name. Using default logger")
|
158
|
+
|
159
|
+
return logging.getLogger(logger_name)
|
160
|
+
|
161
|
+
|
162
|
+
def set_frogml_logger_stdout_verbosity_level(verbose: int, format: str = "text"):
|
163
|
+
"""Set frogml stdout to verbose (a.k.a DEBUG level)
|
164
|
+
|
165
|
+
Args:
|
166
|
+
verbose: Log verbosity level - 0: WARNING, 1:INFO, 2: DEBUG
|
167
|
+
|
168
|
+
Notes:
|
169
|
+
1. https://docs.python.org/3/library/logging.html#logging-levels
|
170
|
+
"""
|
171
|
+
if format == "json":
|
172
|
+
verbose = 0
|
173
|
+
logger: logging.Logger = get_frogml_logger()
|
174
|
+
logger.setLevel(VERBOSITY_LEVEL_MAPPING[verbose])
|
175
|
+
for handler in logger.handlers:
|
176
|
+
if isinstance(handler, logging.StreamHandler):
|
177
|
+
handler.setLevel(VERBOSITY_LEVEL_MAPPING[verbose])
|
178
|
+
|
179
|
+
|
180
|
+
def get_frogml_logger_verbosity_level() -> Optional[int]:
|
181
|
+
"""Get current Frogml logger level.
|
182
|
+
|
183
|
+
Returns:
|
184
|
+
int: Frogml logger level 10 < level < 50.
|
185
|
+
|
186
|
+
Notes:
|
187
|
+
1. https://docs.python.org/3/library/logging.html#logging-levels
|
188
|
+
2. when we update the log level through set_frogml_logger_stdout_verbosity_level we update all handler levels
|
189
|
+
thus returning the first stream handler should be correct
|
190
|
+
"""
|
191
|
+
|
192
|
+
logger: logging.Logger = get_frogml_logger()
|
193
|
+
|
194
|
+
for handler in logger.handlers:
|
195
|
+
if isinstance(handler, logging.StreamHandler):
|
196
|
+
return logging.getLevelName(handler.level)
|
197
|
+
|
198
|
+
|
199
|
+
def set_frogml_logger_propagate(prop: bool):
|
200
|
+
"""Set frogml logger propagation
|
201
|
+
|
202
|
+
Args:
|
203
|
+
prop: True if propagate else False
|
204
|
+
|
205
|
+
"""
|
206
|
+
get_frogml_logger().propagate = prop
|
207
|
+
|
208
|
+
|
209
|
+
def translate_to_frogml_verbosity_level(loglevel: int) -> Optional[int]:
|
210
|
+
"""Get frogml equivalent of the logging verbosity levels
|
211
|
+
|
212
|
+
Args:
|
213
|
+
loglevel: logging log level int
|
214
|
+
"""
|
215
|
+
return REVERSED_VERBOSITY_LEVEL_MAPPING.get(loglevel, None)
|
216
|
+
|
217
|
+
|
218
|
+
def get_frogml_logger_name(fallback_logger_name: Optional[str] = None):
|
219
|
+
if fallback_logger_name:
|
220
|
+
return os.getenv(ENVIRON_LOGGER_TYPE, fallback_logger_name)
|
221
|
+
else:
|
222
|
+
return os.getenv(ENVIRON_LOGGER_TYPE, DEFAULT_LOGGER_NAME)
|
223
|
+
|
224
|
+
|
225
|
+
def get_handler_from_logger(
|
226
|
+
logger: logging.Logger, handler_name: str
|
227
|
+
) -> logging.Handler:
|
228
|
+
matching_handlers = list(
|
229
|
+
filter(lambda h: h.get_name() == handler_name, logger.handlers)
|
230
|
+
)
|
231
|
+
if len(matching_handlers) == 0 and not non_frogml_logger_enabled:
|
232
|
+
raise FrogmlException(
|
233
|
+
f"Error in setting log file. Error message: handler of name {handler_name} was not found in logger"
|
234
|
+
)
|
235
|
+
elif len(matching_handlers) > 1:
|
236
|
+
raise FrogmlException(
|
237
|
+
f"Error in setting log file. Error message: handler of name {handler_name} was found more than once "
|
238
|
+
f"in logger"
|
239
|
+
)
|
240
|
+
|
241
|
+
return matching_handlers[0]
|
242
|
+
|
243
|
+
|
244
|
+
def set_file_handler_log_file(
|
245
|
+
logger: logging.Logger, handler_name: str, log_file: Path
|
246
|
+
):
|
247
|
+
existing_handler = get_handler_from_logger(logger, handler_name)
|
248
|
+
if type(existing_handler) != RotatingFileHandler:
|
249
|
+
raise FrogmlException(
|
250
|
+
f"Error in setting log file. Error message: handler of name {handler_name} is not a file logger handler"
|
251
|
+
)
|
252
|
+
replacement_handler: RotatingFileHandler = copy_file_handler_from_existing(
|
253
|
+
existing_handler, log_file
|
254
|
+
)
|
255
|
+
logger.removeHandler(existing_handler)
|
256
|
+
logger.addHandler(replacement_handler)
|
257
|
+
|
258
|
+
|
259
|
+
def copy_file_handler_from_existing(
|
260
|
+
handler: RotatingFileHandler, log_file: Path
|
261
|
+
) -> RotatingFileHandler:
|
262
|
+
return RotatingFileHandler(
|
263
|
+
log_file,
|
264
|
+
mode=handler.mode,
|
265
|
+
maxBytes=int(handler.maxBytes),
|
266
|
+
backupCount=int(handler.backupCount),
|
267
|
+
encoding=handler.encoding,
|
268
|
+
delay=handler.delay,
|
269
|
+
)
|
270
|
+
|
271
|
+
|
272
|
+
def set_handler_verbosity(logger: logging.Logger, handler_name: str, log_level: int):
|
273
|
+
handler = get_handler_from_logger(logger, handler_name)
|
274
|
+
handler.setLevel(log_level)
|
275
|
+
|
276
|
+
|
277
|
+
def non_frogml_logger_enabled():
|
278
|
+
return os.getenv(AIRFLOW_ENV_FLAG) is not None
|
@@ -0,0 +1,79 @@
|
|
1
|
+
version: 1
|
2
|
+
disable_existing_loggers: false
|
3
|
+
|
4
|
+
formatters:
|
5
|
+
brief:
|
6
|
+
format: '%(message)s'
|
7
|
+
semi_precise:
|
8
|
+
format: "%(asctime)s [%(levelname)-5.5s] %(message)s"
|
9
|
+
datefmt: '%Y-%m-%d %H:%M:%S'
|
10
|
+
precise:
|
11
|
+
format: '%(asctime)s %(levelname)-8s %(module)s - %(lineno)d - %(message)s'
|
12
|
+
datefmt: '%Y-%m-%d %H:%M:%S'
|
13
|
+
remote:
|
14
|
+
class: pythonjsonlogger.json.JsonFormatter
|
15
|
+
format: '%(asctime)s %(process)d %(levelname)s %(module)s %(lineno)d %(message)s'
|
16
|
+
datefmt: '%Y-%m-%dT%H:%M:%S'
|
17
|
+
json:
|
18
|
+
class: pythonjsonlogger.json.JsonFormatter
|
19
|
+
format: '%(asctime)s %(process)d %(levelname)s %(module)s %(lineno)d %(message)s'
|
20
|
+
datefmt: '%Y-%m-%dT%H:%M:%S'
|
21
|
+
|
22
|
+
handlers:
|
23
|
+
console:
|
24
|
+
class : logging.StreamHandler
|
25
|
+
formatter: brief
|
26
|
+
level : INFO
|
27
|
+
stream : ext://sys.stdout
|
28
|
+
file_handler:
|
29
|
+
class: logging.handlers.RotatingFileHandler
|
30
|
+
level: DEBUG
|
31
|
+
formatter: precise
|
32
|
+
filename: ""
|
33
|
+
maxBytes: 10485760 # 10MB
|
34
|
+
backupCount: 5
|
35
|
+
encoding: utf8
|
36
|
+
remote_console:
|
37
|
+
class: logging.StreamHandler
|
38
|
+
formatter: remote
|
39
|
+
level: DEBUG
|
40
|
+
stream: ext://sys.stdout
|
41
|
+
model:
|
42
|
+
class: logging.StreamHandler
|
43
|
+
formatter: json
|
44
|
+
level: INFO
|
45
|
+
stream: ext://sys.stdout
|
46
|
+
build_log_file_handler:
|
47
|
+
class: logging.handlers.RotatingFileHandler
|
48
|
+
level: DEBUG
|
49
|
+
formatter: semi_precise
|
50
|
+
filename: ""
|
51
|
+
maxBytes: 10485760 # 10MB
|
52
|
+
backupCount: 5
|
53
|
+
encoding: utf8
|
54
|
+
|
55
|
+
loggers:
|
56
|
+
frogml:
|
57
|
+
level: DEBUG
|
58
|
+
handlers: [console, file_handler]
|
59
|
+
propagate: false
|
60
|
+
frogml_remote:
|
61
|
+
level: DEBUG
|
62
|
+
handlers: [remote_console]
|
63
|
+
propagate: false
|
64
|
+
frogml_model:
|
65
|
+
level: DEBUG
|
66
|
+
handlers: [model]
|
67
|
+
propagate: false
|
68
|
+
feature_store:
|
69
|
+
level: DEBUG
|
70
|
+
handlers: [model]
|
71
|
+
propagate: false
|
72
|
+
build_local:
|
73
|
+
level: DEBUG
|
74
|
+
handlers: [build_log_file_handler, console]
|
75
|
+
propagate: false
|
76
|
+
docker_internal:
|
77
|
+
level: DEBUG
|
78
|
+
handlers: [console]
|
79
|
+
propagate: false
|
@@ -0,0 +1,47 @@
|
|
1
|
+
import logging
|
2
|
+
import platform
|
3
|
+
import sys
|
4
|
+
|
5
|
+
import requests
|
6
|
+
|
7
|
+
from frogml_cli import __version__ as cli_version
|
8
|
+
|
9
|
+
logger = logging.getLogger(__name__)
|
10
|
+
|
11
|
+
|
12
|
+
def _amplitude_url():
|
13
|
+
return "https://api2.amplitude.com/2/httpapi"
|
14
|
+
|
15
|
+
|
16
|
+
def _platform_info():
|
17
|
+
return platform.platform()
|
18
|
+
|
19
|
+
|
20
|
+
def _python_version():
|
21
|
+
return "{major}.{minor}.{micro}".format(
|
22
|
+
major=sys.version_info.major,
|
23
|
+
minor=sys.version_info.minor,
|
24
|
+
micro=sys.version_info.micro,
|
25
|
+
)
|
26
|
+
|
27
|
+
|
28
|
+
def log_event(properties, user_id):
|
29
|
+
properties["sdk_version"] = cli_version
|
30
|
+
properties["python_version"] = _python_version()
|
31
|
+
properties["platform_info"] = _platform_info()
|
32
|
+
|
33
|
+
event = [
|
34
|
+
{
|
35
|
+
"event_type": "sdk-event",
|
36
|
+
"user_id": user_id,
|
37
|
+
"event_properties": properties,
|
38
|
+
"ip": "$remote",
|
39
|
+
}
|
40
|
+
]
|
41
|
+
|
42
|
+
event_data = {"events": event}
|
43
|
+
|
44
|
+
try:
|
45
|
+
return requests.post(_amplitude_url(), json=event_data, timeout=1)
|
46
|
+
except Exception as e:
|
47
|
+
logger.debug(str(e))
|
frogml_cli/main.py
ADDED
File without changes
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class Color:
|
2
|
+
PURPLE = "\033[95m"
|
3
|
+
CYAN = "\033[96m"
|
4
|
+
WHITE = "\033[97m"
|
5
|
+
GREY = "\033[98m"
|
6
|
+
DARKCYAN = "\033[36m"
|
7
|
+
BLUE = "\033[94m"
|
8
|
+
GREEN = "\033[92m"
|
9
|
+
YELLOW = "\033[93m"
|
10
|
+
RED = "\033[91m"
|
11
|
+
BOLD = "\033[1m"
|
12
|
+
UNDERLINE = "\033[4m"
|
13
|
+
END = "\033[0m"
|