<reponame>Chromico/bk-base
# -*- coding: utf-8 -*-
"""
Tencent is pleased to support the open source community by making BK-BASE 蓝鲸基础平台 available.

Copyright (C) 2021 THL A29 Limited, a Tencent company.  All rights reserved.

BK-BASE 蓝鲸基础平台 is licensed under the MIT License.

License for BK-BASE 蓝鲸基础平台:
--------------------------------------------------------------------
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"""

from .base import BaseTest


class TestModel(BaseTest):
    def models(self):
        data = [
            {
                "model_id": "xxx",
                "model_version_id": "xxx",
                "model_name": "xx",
                "description": "xx",
                "version_description": "xxx",
            },
            {
                "model_id": "xxx",
                "model_version_id": "xxx",
                "model_name": "xx",
                "description": "xx",
                "version_description": "xxx",
            },
        ]
        return self.success_response(data)

    def model_instances(self):
        data = {
            "instance_id": 1,
            "processing_id": "test",
            "result_table_id": "test",
            "model_version_id": 1,
            "model_release_id": 1,
        }
        return self.success_response(data)

    def get_model_version(self):
        data = {
            "has_training": True,
            "model_status": "complete",
            "model_version_id": 17,
            "execute_path": None,
            "updated_at": "2018-09-06 11:16:19",
            "train_mode": None,
            "deleted_by": None,
            "id": 923,
            "updated_by": "abc",
            "deleted_at": None,
            "run_context": "local",
            "created_by": "xxx",
            "code_addr": None,
            "project_id": 3481,
            "model_id": "upgrade_test",
            "model_config_template": {
                "training_when_serving": False,
                "args": {
                    "node_code_node_643f7b": {
                        "index": 0,
                        "model_node_name": "代码",
                        "node_en_name": "code_node",
                        "description": "代码编辑节点， 用户可以通过写python代码实现自己的training(训练)、" "serving(应用)或transform(转换)逻辑",
                        "tags": [],
                        "node_runner_type": "serving_training",
                        "node_zh_name": "代码",
                        "output_fields": [
                            {
                                "field": "AGE",
                                "type": "double",
                                "description": "1940年前建成自用单位比例",
                            },
                            {
                                "field": "timestamp",
                                "type": "int",
                                "description": "timestamp",
                            },
                        ],
                        "other_training_info": None,
                        "custom_node_id": "node_code_node_a73dc2",
                        "use_other_training": False,
                        "node_type": "data_preparing",
                        "model_node_id": "node_code_node_643f7b",
                        "is_generalizable": True,
                        "children_model_node_ids": ["node_output_node_1fa807"],
                        "node_args": {
                            "has_training": {
                                "default_value": False,
                                "arg_type": "boolean",
                                "node_en_name": "code_node",
                                "description": "训练应用模式——会依次执行代码中实现的training和serving函数\n" "转换模式——针对验证集执行transform函数",
                                "is_output_field": False,
                                "is_advance_arg": False,
                                "created_at": "2017-09-13 09:51:44",
                                "updated_at": "2017-09-13 09:51:44",
                                "value": False,
                                "has_custom_performance": True,
                                "arg_en_name": "has_training",
                                "output_field_type": None,
                                "used_by": "developer",
                                "arg_index": 2,
                                "properties": {"is_required": True},
                                "arg_zh_name": "代码运行模式",
                            },
                            "run_context": {
                                "default_value": "local",
                                "arg_type": "string",
                                "node_en_name": "code_node",
                                "description": "如果运行环境是LOCAL， 则输入的数据格式是 pandas DataFrame,"
                                "如果运行环境是SPARK, 则输入的数据格式是 spark DataFrame;",
                                "is_output_field": False,
                                "is_advance_arg": False,
                                "created_at": "2017-09-13 10:23:29",
                                "updated_at": "2017-09-13 10:23:29",
                                "value": "local",
                                "has_custom_performance": False,
                                "arg_en_name": "run_context",
                                "output_field_type": None,
                                "used_by": "developer",
                                "arg_index": 1,
                                "properties": {
                                    "is_required": True,
                                    "optional": ["local", "spark"],
                                },
                                "arg_zh_name": "代码运行环境",
                            },
                            "max_process_groups": {
                                "default_value": -1,
                                "arg_type": "int",
                                "node_en_name": "code_node",
                                "description": "当数据时分组的时候，设置处理的最大分组数，可以解决使用全部分组数据处理过慢。" "（-1为使用全部分组）",
                                "is_output_field": False,
                                "is_advance_arg": True,
                                "created_at": "2017-11-13 12:15:50",
                                "updated_at": "2017-11-13 12:15:50",
                                "value": -1,
                                "has_custom_performance": False,
                                "arg_en_name": "max_process_groups",
                                "output_field_type": None,
                                "used_by": "developer",
                                "arg_index": 6,
                                "properties": {"is_required": False},
                                "arg_zh_name": "最大处理分组数",
                            },
                            "custom_args": {
                                "default_value": [],
                                "arg_type": "json",
                                "node_en_name": "code_node",
                                "description": "自定义参数。模型应用时，该代码节点需要从用户端拿到的配置参数，" "需要模型开发者填写每个参数的英文名，中文名，类型，默认值，描述",
                                "is_output_field": False,
                                "is_advance_arg": False,
                                "created_at": "2017-11-23 04:01:22",
                                "updated_at": "2017-11-23 04:01:22",
                                "value": [],
                                "has_custom_performance": True,
                                "arg_en_name": "custom_args",
                                "output_field_type": None,
                                "used_by": "developer",
                                "arg_index": 7,
                                "properties": {"is_required": False},
                                "arg_zh_name": "自定义参数",
                            },
                            "react_sample_dbs": {
                                "default_value": None,
                                "arg_type": "json",
                                "node_en_name": "code_node",
                                "description": "用户可以在代码节点中访问使用的样本库，可以配置多个，" "用户系统提供的接口使用访问相应样本库的数据。",
                                "is_output_field": False,
                                "is_advance_arg": True,
                                "created_at": "2018-06-07 22:09:24",
                                "updated_at": "2018-06-07 22:09:24",
                                "value": None,
                                "has_custom_performance": True,
                                "arg_en_name": "react_sample_dbs",
                                "output_field_type": None,
                                "used_by": "developer",
                                "arg_index": 8,
                                "properties": {"is_required": False},
                                "arg_zh_name": "代码可访问样本库",
                            },
                            "new_fields": {
                                "default_value": [],
                                "arg_type": "json",
                                "node_en_name": "code_node",
                                "description": "代码处理完成输入的DataFrame之后， 返回的DataFrame中新增的字段",
                                "is_output_field": False,
                                "is_advance_arg": False,
                                "created_at": "2017-09-13 10:29:12",
                                "updated_at": "2017-09-13 10:29:12",
                                "value": [
                                    {
                                        "field": "timestamp",
                                        "type": "int",
                                        "description": "timestamp",
                                    }
                                ],
                                "has_custom_performance": True,
                                "arg_en_name": "new_fields",
                                "output_field_type": None,
                                "used_by": "developer",
                                "arg_index": 4,
                                "properties": {"is_required": False},
                                "arg_zh_name": "新增字段",
                            },
                            "source_code": {
                                "default_value": '"""\n    training 训练应用模式下, 在模型训练的时候执行的函数,\n    '
                                "serving 训练应用模式下, 在模型应用的时候执行的函数,\n    "
                                "transform 转换模式下, 在模型进行转换时执行的函数;\n\n    "
                                "影响代码节点执行逻辑的参数有两个:\n        "
                                "节点运行模式:\n            "
                                "训练并验证(默认): 节点用training(transform)函数执行训练集数据, "
                                "用serving(transform)函数执行验证集数据\n            "
                                "仅验证: 节点仅用training(transform)函数执行训练集数据;\n            "
                                "仅训练: 节点仅用serving(transform)函数执行验证集数据;\n        "
                                "代码运行模式:\n            "
                                "训练应用模式: 需实现training和serving函数, "
                                "serving函数可使用training函数训练得到的模型\n            "
                                "转换模式: 需实现transform函数, 可分别对训练集或者验证集进行数据转换\n\n    "
                                "注意:\n        1 由于training和serving的调度周期存在差异,\n            "
                                "所以二者并不能共享代码文件中定义的全局变量;\n        "
                                "2 training 和 serving "
                                "唯一的交互是training训练得到的结果(model),\n            "
                                "serving函数可以使用;\n\n    常用库import:\n        "
                                "import pandas as pd\n        import numpy as np\n        "
                                "from bkdata.spark_util import get_spark_content, "
                                "get_spark_sql_content\n        spark_content = "
                                "get_spark_content(app_name='test_content')\n        "
                                "spark_sql_content = "
                                'get_spark_sql_content(app_name=\'test_sql_content\')\n"""\n\n'
                                'def training(args, df):\n    """\n        参数:\n            '
                                "args: 在节点配置页面指定的模型参数；\n            df: 输入数据, "
                                "如果运行环境是LOCAL， 则是 pandas DataFrame,\n                "
                                "如果运行环境是SPARK, 则是 spark DataFrame;\n\n        "
                                "返回：\n            "
                                "df: 处理之后的ＤataFrame, 要求和输入的df保持同一类型;\n            "
                                "model: 模型训练的结果, 该结果会被序列化之后保存起来,\n                "
                                '当执行serving函数的时候, 会被反序列化传给serving;\n    """\n    raise '
                                'NotImplementedError("Training function is not implemented.")\n\n\n'
                                'def serving(args, df, trained_result=None):\n    """\n        '
                                "参数:\n            args: 在节点配置页面指定的模型参数；\n            "
                                "df: 输入数据, 如果运行环境是LOCAL， "
                                "则是 pandas DataFrame,\n                "
                                "如果运行环境是SPARK, 则是 spark DataFrame;\n            "
                                "trained_result: 模型训练的结果, 即training函数返回的model；\n\n        "
                                "返回：\n            "
                                'df: 处理之后的ＤataFrame, 要求和输入的df保持同一类型;\n    """\n    '
                                "raise "
                                'NotImplementedError("Serving function is not implemented.")\n\n\n'
                                'def transform(args, df):\n    """\n        参数:\n            '
                                "args: 在节点配置页面指定的模型参数；\n            df: 输入数据, "
                                "如果运行环境是LOCAL， 则是 pandas DataFrame,\n                "
                                "如果运行环境是SPARK, 则是 spark DataFrame;\n\n        "
                                "返回：\n            df: 处理之后的ＤataFrame, "
                                '要求和输入的df保持同一类型;\n    """\n    '
                                'raise NotImplementedError("Transform function is not implemented.")',
                                "arg_type": "string",
                                "node_en_name": "code_node",
                                "description": "需要编写的源代码",
                                "is_output_field": False,
                                "is_advance_arg": False,
                                "created_at": "2017-09-13 10:25:24",
                                "updated_at": "2017-09-13 10:25:24",
                                "value": "xxx",
                                "has_custom_performance": True,
                                "arg_en_name": "source_code",
                                "output_field_type": None,
                                "used_by": "developer",
                                "arg_index": 3,
                                "properties": {"is_required": True},
                                "arg_zh_name": "源代码",
                            },
                            "access_null_input": {
                                "default_value": False,
                                "arg_type": "boolean",
                                "node_en_name": "code_node",
                                "description": "是否接受Null值作为此代码节点的输入，默认情况下， 当输入数据为Null时，"
                                "会跳过该节点的执行逻辑，\n如果该值为True， "
                                "则开发者需要在模型中处理输入为Null情况。",
                                "is_output_field": False,
                                "is_advance_arg": True,
                                "created_at": "2017-10-29 06:09:55",
                                "updated_at": "2017-10-29 06:09:55",
                                "value": False,
                                "has_custom_performance": False,
                                "arg_en_name": "access_null_input",
                                "output_field_type": None,
                                "used_by": "developer",
                                "arg_index": 5,
                                "properties": {"is_required": False},
                                "arg_zh_name": "是否接受NULL值输入",
                            },
                        },
                        "input_source_nums": 1,
                        "parent_model_node_ids": ["node_input_node_7aaeda"],
                        "cur_context": "any",
                        "node_graph_config": {
                            "status": "configured",
                            "model_id": "upgrade_test",
                            "project_id": 3481,
                            "model_status": "building",
                            "name": "代码",
                            "model_version_id": 16,
                            "title": "",
                            "auto": False,
                            "created_at": "2018-08-28 10:18:14",
                            "component": "code_node",
                            "updated_at": "2018-08-28 10:20:04",
                            "id": "node_code_node_643f7b",
                            "y": 190,
                            "x": 309,
                            "session_key": "<KEY>",
                            "type": "model-node",
                            "model_name": "升级测试模型",
                        },
                    }
                },
                "is_serving_scheduler_paras_set": False,
                "is_training_scheduler_paras_set": False,
                "output": {
                    "node_output_node_1fa807": {
                        "index": 0,
                        "model_node_name": "数据输出",
                        "node_en_name": "output_node",
                        "description": "数据输出节点, 输出为Result Table表",
                        "tags": [],
                        "node_runner_type": "serving_training",
                        "node_zh_name": "数据输出",
                        "output_fields": [
                            {
                                "field": "AGE",
                                "type": "double",
                                "description": "1940年前建成自用单位比例",
                            },
                            {
                                "field": "timestamp",
                                "type": "int",
                                "description": "timestamp",
                            },
                        ],
                        "other_training_info": None,
                        "custom_node_id": "node_output_node_9b981a",
                        "use_other_training": False,
                        "node_type": "data",
                        "model_node_id": "node_output_node_1fa807",
                        "is_generalizable": True,
                        "children_model_node_ids": [],
                        "node_args": {
                            "storages_args": {
                                "default_value": None,
                                "arg_type": "json",
                                "node_en_name": "output_node",
                                "description": "存储参数",
                                "is_output_field": False,
                                "is_advance_arg": False,
                                "created_at": "2016-10-18 17:07:31",
                                "updated_at": "2018-04-05 00:12:07",
                                "value": None,
                                "has_custom_performance": False,
                                "arg_en_name": "storages_args",
                                "output_field_type": None,
                                "used_by": "user",
                                "arg_index": 4,
                                "properties": {"is_required": False},
                                "arg_zh_name": "存储参数",
                            },
                            "output_group_info": {
                                "default_value": False,
                                "arg_type": "boolean",
                                "node_en_name": "output_node",
                                "description": "业务ID",
                                "is_output_field": False,
                                "is_advance_arg": False,
                                "created_at": "2018-06-07 22:12:16",
                                "updated_at": "2018-06-07 22:12:16",
                                "value": False,
                                "has_custom_performance": False,
                                "arg_en_name": "output_group_info",
                                "output_field_type": None,
                                "used_by": "developer",
                                "arg_index": 1,
                                "properties": {"is_required": False},
                                "arg_zh_name": "是否输出分组信息",
                            },
                            "table_zh_name": {
                                "default_value": None,
                                "arg_type": "string",
                                "node_en_name": "output_node",
                                "description": "输出数据使用的中文表名",
                                "is_output_field": False,
                                "is_advance_arg": False,
                                "created_at": "2018-06-07 22:10:53",
                                "updated_at": "2018-06-07 22:10:53",
                                "value": None,
                                "has_custom_performance": False,
                                "arg_en_name": "table_zh_name",
                                "output_field_type": None,
                                "used_by": "user",
                                "arg_index": 6,
                                "properties": {"is_required": False},
                                "arg_zh_name": "输出中文名",
                            },
                            "table_name": {
                                "default_value": None,
                                "arg_type": "string",
                                "node_en_name": "output_node",
                                "description": "输出数据使用的表名,以Result Table为输出目标",
                                "is_output_field": False,
                                "is_advance_arg": False,
                                "created_at": "2016-10-18 17:07:31",
                                "updated_at": "2018-04-05 00:12:07",
                                "value": None,
                                "has_custom_performance": False,
                                "arg_en_name": "table_name",
                                "output_field_type": None,
                                "used_by": "user",
                                "arg_index": 5,
                                "properties": {"is_required": False},
                                "arg_zh_name": "输出表",
                            },
                            "biz_id": {
                                "default_value": None,
                                "arg_type": "int",
                                "node_en_name": "output_node",
                                "description": "业务ID",
                                "is_output_field": False,
                                "is_advance_arg": False,
                                "created_at": "2016-10-18 17:07:31",
                                "updated_at": "2018-04-05 00:12:07",
                                "value": None,
                                "has_custom_performance": False,
                                "arg_en_name": "biz_id",
                                "output_field_type": None,
                                "used_by": "user",
                                "arg_index": 2,
                                "properties": {"is_required": False},
                                "arg_zh_name": "业务ID",
                            },
                            "project_id": {
                                "default_value": None,
                                "arg_type": "int",
                                "node_en_name": "output_node",
                                "description": "项目ID",
                                "is_output_field": False,
                                "is_advance_arg": False,
                                "created_at": "2016-10-18 17:07:31",
                                "updated_at": "2018-04-05 00:12:07",
                                "value": None,
                                "has_custom_performance": False,
                                "arg_en_name": "project_id",
                                "output_field_type": None,
                                "used_by": "user",
                                "arg_index": 3,
                                "properties": {"is_required": False},
                                "arg_zh_name": "项目ID",
                            },
                        },
                        "input_source_nums": 1,
                        "parent_model_node_ids": ["node_code_node_643f7b"],
                        "cur_context": "any",
                        "node_graph_config": {
                            "status": "configured",
                            "model_id": "upgrade_test",
                            "project_id": 3481,
                            "model_status": "building",
                            "name": "数据输出",
                            "model_version_id": 16,
                            "title": "",
                            "auto": False,
                            "created_at": "2018-08-28 10:18:14",
                            "component": "output_node",
                            "updated_at": "2018-08-28 10:20:04",
                            "id": "node_output_node_1fa807",
                            "y": 221,
                            "x": 607,
                            "session_key": "<KEY>",
                            "type": "model-node",
                            "model_name": "升级测试模型",
                        },
                    }
                },
                "training_scheduler_params": {"period": None, "first_run_time": None},
                "input": {
                    "node_input_node_7aaeda": {
                        "index": 0,
                        "model_node_name": "新版输入V2",
                        "node_en_name": "input_node_v2",
                        "description": "数据输入节点, 输入为Result Table表",
                        "tags": [],
                        "node_runner_type": "serving_training",
                        "node_zh_name": "数据输入V2",
                        "output_fields": [
                            {
                                "field": "AGE",
                                "type": "double",
                                "description": "1940年前建成自用单位比例",
                            }
                        ],
                        "other_training_info": None,
                        "custom_node_id": "node_input_node_v2_0d0c9a",
                        "use_other_training": False,
                        "node_type": "data",
                        "model_node_id": "node_input_node_7aaeda",
                        "is_generalizable": True,
                        "children_model_node_ids": ["node_code_node_643f7b"],
                        "node_args": {
                            "building_sample_db": {
                                "default_value": {
                                    "ts_properties": {
                                        "ts_agg": "last",
                                        "ts_period": None,
                                        "ts_depend": None,
                                        "ts_agg_orient": "up",
                                        "ts_field": None,
                                        "ts_freq": None,
                                    },
                                    "group_fields": [],
                                },
                                "arg_type": "json",
                                "node_en_name": "input_node_v2",
                                "used_by": "developer",
                                "value": {
                                    "ts_properties": {
                                        "ts_agg": "last",
                                        "ts_period": None,
                                        "ts_depend": None,
                                        "ts_agg_orient": "up",
                                        "ts_field": None,
                                        "ts_freq": None,
                                    },
                                    "group_fields": [],
                                },
                                "arg_en_name": "building_sample_db",
                                "is_advance_arg": False,
                                "properties": None,
                            },
                            "group_fields": {
                                "default_value": None,
                                "arg_type": "list",
                                "node_en_name": "input_node_v2",
                                "description": "分组字段列表， 用于将数据分为多个数据集",
                                "is_output_field": False,
                                "arg_index": 12,
                                "created_at": "2018-04-12 20:17:11",
                                "arg_en_name": "group_fields",
                                "updated_at": "2018-04-12 20:17:11",
                                "value": None,
                                "properties": {
                                    "source": "result_table",
                                    "list": "field",
                                },
                                "has_custom_performance": False,
                                "output_field_type": None,
                                "is_advance_arg": False,
                                "used_by": "user",
                                "arg_zh_name": "分组字段",
                            },
                            "serving_fields_mapping": {
                                "default_value": None,
                                "arg_type": "json",
                                "node_en_name": "input_node_v2",
                                "description": "验证集字段映射， 用于验证集合不是从训练集样本库切分出来的情况",
                                "is_output_field": False,
                                "arg_index": 11,
                                "created_at": "2018-04-12 20:15:51",
                                "arg_en_name": "serving_fields_mapping",
                                "updated_at": "2018-04-12 20:15:51",
                                "value": None,
                                "properties": {"depend": {"test_data_radio": 0}},
                                "has_custom_performance": False,
                                "output_field_type": None,
                                "is_advance_arg": False,
                                "used_by": "both",
                                "arg_zh_name": "字段映射",
                            },
                            "data_start_time": {
                                "default_value": "-7d",
                                "arg_type": "time",
                                "node_en_name": "input_node_v2",
                                "description": "样本数据的开始时间, 默认格式:'2016-10-17 23:53:49', "
                                "可以使用:'now'/'-1d'/'-7d'/'-1h'/'-48h'等描述方式, "
                                "只有当节点的serving方式是offline的时候, 此参数有效",
                                "is_output_field": False,
                                "arg_index": 9,
                                "created_at": "2018-04-12 20:14:23",
                                "arg_en_name": "data_start_time",
                                "updated_at": "2018-04-12 20:14:23",
                                "value": "-7d",
                                "properties": None,
                                "has_custom_performance": False,
                                "output_field_type": None,
                                "is_advance_arg": False,
                                "used_by": "user",
                                "arg_zh_name": "输入数据开始时间",
                            },
                            "serving_use_fields": {
                                "default_value": None,
                                "arg_type": "list",
                                "node_en_name": "input_node_v2",
                                "description": "模型执行 serving 的时候， 输入数据必须提供的字段",
                                "is_output_field": False,
                                "arg_index": 1,
                                "created_at": "2018-04-12 20:11:51",
                                "arg_en_name": "serving_use_fields",
                                "updated_at": "2018-04-12 20:11:51",
                                "value": ["AGE", "AGE"],
                                "properties": {"list": "field"},
                                "has_custom_performance": False,
                                "output_field_type": None,
                                "is_advance_arg": False,
                                "used_by": "developer",
                                "arg_zh_name": "模型必须字段",
                            },
                            "is_training_serving_same_source": {
                                "default_value": {
                                    "is_training_serving_same_source": False,
                                    "sample_start_time": "",
                                    "sample_end_time": "",
                                },
                                "arg_type": "json",
                                "node_en_name": "input_node_v2",
                                "description": "训练数据和应用数据来自相同的结果表，\r\n如果模型开发者把此项置为True，\r\n"
                                "则应用改模型的人只需要选择一个RT表作为输入， \r\n"
                                "而不用同时选择样本库和应用数据输入表。\r\n如果选择了此项，"
                                "则在固定应用配置参数中是否选择sample_db_name无效",
                                "is_output_field": False,
                                "arg_index": 16,
                                "created_at": "2018-04-12 20:16:18",
                                "arg_en_name": "is_training_serving_same_source",
                                "updated_at": "2018-04-12 20:16:18",
                                "value": {
                                    "is_training_serving_same_source": True,
                                    "sample_start_time": "-1d",
                                    "sample_end_time": "now",
                                },
                                "properties": None,
                                "has_custom_performance": False,
                                "output_field_type": None,
                                "is_advance_arg": True,
                                "used_by": "developer",
                                "arg_zh_name": "训练和应用数据源相同",
                            },
                            "ts_depend": {
                                "default_value": None,
                                "arg_type": "time",
                                "node_en_name": "input_node_v2",
                                "description": "用于时间序列数据，时序数据在特征提取转换等处理时需要用到相关的历史数据，" "参数用于指定依赖历史数据的长度",
                                "is_output_field": False,
                                "arg_index": 3,
                                "created_at": "2018-04-12 20:12:35",
                                "arg_en_name": "ts_depend",
                                "updated_at": "2018-04-12 20:12:35",
                                "value": None,
                                "properties": None,
                                "is_dynamic": True,
                                "has_custom_performance": False,
                                "output_field_type": None,
                                "is_advance_arg": True,
                                "used_by": "developer",
                                "arg_zh_name": "时序数据历史依赖",
                            },
                            "label_field": {
                                "default_value": None,
                                "arg_type": "field",
                                "node_en_name": "input_node_v2",
                                "description": "训练数据的标签字段",
                                "is_output_field": False,
                                "arg_index": 2,
                                "created_at": "2018-04-12 20:12:05",
                                "arg_en_name": "label_field",
                                "updated_at": "2018-04-12 20:12:05",
                                "value": "AGE",
                                "properties": {},
                                "has_custom_performance": False,
                                "output_field_type": None,
                                "is_advance_arg": False,
                                "used_by": "developer",
                                "arg_zh_name": "标签字段",
                            },
                            "sample_db_name": {
                                "default_value": None,
                                "arg_type": "string",
                                "node_en_name": "input_node_v2",
                                "description": "样本库， 用于模型训练的输入数据",
                                "is_output_field": False,
                                "arg_index": 0,
                                "created_at": "2018-04-12 20:11:37",
                                "arg_en_name": "sample_db_name",
                                "updated_at": "2018-04-12 20:11:37",
                                "value": None,
                                "properties": {"string": "sample_db"},
                                "has_custom_performance": False,
                                "output_field_type": None,
                                "is_advance_arg": False,
                                "used_by": "both",
                                "arg_zh_name": "样本库",
                            },
                            "training_fields_mapping": {
                                "default_value": None,
                                "arg_type": "json",
                                "node_en_name": "input_node_v2",
                                "description": "训练数据字段映射， 用于验证集合不是从训练集样本库切分出来的情况",
                                "is_output_field": False,
                                "arg_index": 4,
                                "created_at": "2018-04-12 20:19:09",
                                "arg_en_name": "training_fields_mapping",
                                "updated_at": "2018-04-12 20:19:09",
                                "value": None,
                                "properties": None,
                                "has_custom_performance": False,
                                "output_field_type": None,
                                "is_advance_arg": False,
                                "used_by": "user",
                                "arg_zh_name": "字段映射",
                            },
                            "data_end_time": {
                                "default_value": "now",
                                "arg_type": "time",
                                "node_en_name": "input_node_v2",
                                "description": "样本数据的结束时间, 默认格式:'2016-10-17 23:53:49', "
                                "可以使用:'now'/'-1d'/'-7d'/'-1h'/'-48h'等描述方式,"
                                "只有当节点的serving方式是offline的时候, 此参数有效",
                                "is_output_field": False,
                                "arg_index": 10,
                                "created_at": "2018-04-12 20:15:07",
                                "arg_en_name": "data_end_time",
                                "updated_at": "2018-04-12 20:15:07",
                                "value": "now",
                                "properties": None,
                                "has_custom_performance": False,
                                "output_field_type": None,
                                "is_advance_arg": False,
                                "used_by": "user",
                                "arg_zh_name": "输入数据结束时间",
                            },
                            "evaluate_sample_db_name": {
                                "default_value": None,
                                "arg_type": "string",
                                "node_en_name": "input_node_v2",
                                "description": "验证样本库， 用于模型验证的输入数据",
                                "is_output_field": False,
                                "arg_index": 6,
                                "created_at": "2018-04-12 20:20:55",
                                "arg_en_name": "evaluate_sample_db_name",
                                "updated_at": "2018-04-12 20:20:55",
                                "value": None,
                                "properties": {
                                    "depend": {"test_data_radio": 0},
                                    "string": "sample_db",
                                },
                                "has_custom_performance": False,
                                "output_field_type": None,
                                "is_advance_arg": False,
                                "used_by": "developer",
                                "arg_zh_name": "验证样本库",
                            },
                            "test_data_radio": {
                                "default_value": 0,
                                "arg_type": "float",
                                "node_en_name": "input_node_v2",
                                "description": "测试数据在样本库中的占比， 样本库的数据会被以此比例分割为两部分，" "训练集以及测试集",
                                "is_output_field": False,
                                "arg_index": 5,
                                "created_at": "2018-04-12 20:13:45",
                                "arg_en_name": "test_data_radio",
                                "updated_at": "2018-04-12 20:13:45",
                                "value": 0.5,
                                "properties": {"performance": "slider"},
                                "has_custom_performance": False,
                                "output_field_type": None,
                                "is_advance_arg": False,
                                "used_by": "developer",
                                "arg_zh_name": "验证集数据来源",
                            },
                            "input_result_table": {
                                "default_value": None,
                                "arg_type": "string",
                                "node_en_name": "input_node_v2",
                                "description": "输入数据,以Result Table为输入源",
                                "is_output_field": False,
                                "arg_index": 8,
                                "created_at": "2018-04-12 20:13:23",
                                "arg_en_name": "input_result_table",
                                "updated_at": "2018-04-12 20:13:23",
                                "value": None,
                                "properties": {"string": "result_table"},
                                "has_custom_performance": False,
                                "output_field_type": None,
                                "is_advance_arg": False,
                                "used_by": "user",
                                "arg_zh_name": "输入表",
                            },
                        },
                        "input_source_nums": 0,
                        "parent_model_node_ids": [],
                        "cur_context": "any",
                        "node_graph_config": {
                            "status": "configured",
                            "model_id": "upgrade_test",
                            "session_key": "13909da4cdd442569d5e21d7ee5df5b0",
                            "model_status": "building",
                            "name": "新版输入V2",
                            "model_version_id": 15,
                            "title": "",
                            "auto": False,
                            "created_at": "2018-08-28 10:04:46",
                            "component": "input_node_v2",
                            "updated_at": None,
                            "created_by": "abc",
                            "model_name": "升级测试模型",
                            "version_description": "new test",
                            "y": 166,
                            "x": 116,
                            "project_id": 3481,
                            "type": "model-input",
                            "id": "node_input_node_7aaeda",
                        },
                    }
                },
                "serving_scheduler_params": {
                    "serving_mode": None,
                    "period": None,
                    "first_run_time": None,
                },
            },
            "description": "升级测试模型",
            "model_alias": None,
            "scene_name": None,
            "biz_id": 0,
            "is_public": False,
            "is_latest": True,
            "properties": {},
            "is_deleted": False,
            "created_at": "2018-08-28 10:36:43",
            "model_name": "升级测试模型",
            "model_type": "flow",
            "version_description": "16",
            "template_id": None,
            "serving_mode": "realtime",
        }
        return self.success_response(data)

# -*- coding: utf-8 -*-
"""
Tencent is pleased to support the open source community by making BK-BASE 蓝鲸基础平台 available.

Copyright (C) 2021 THL A29 Limited, a Tencent company.  All rights reserved.

BK-BASE 蓝鲸基础平台 is licensed under the MIT License.

License for BK-BASE 蓝鲸基础平台:
--------------------------------------------------------------------
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"""

from .base import BaseTest


class TestModel(BaseTest):
    def models(self):
        data = [
            {
                "model_id": "xxx",
                "model_version_id": "xxx",
                "model_name": "xx",
                "description": "xx",
                "version_description": "xxx",
            },
            {
                "model_id": "xxx",
                "model_version_id": "xxx",
                "model_name": "xx",
                "description": "xx",
                "version_description": "xxx",
            },
        ]
        return self.success_response(data)

    def model_instances(self):
        data = {
            "instance_id": 1,
            "processing_id": "test",
            "result_table_id": "test",
            "model_version_id": 1,
            "model_release_id": 1,
        }
        return self.success_response(data)

    def get_model_version(self):
        data = {
            "has_training": True,
            "model_status": "complete",
            "model_version_id": 17,
            "execute_path": None,
            "updated_at": "2018-09-06 11:16:19",
            "train_mode": None,
            "deleted_by": None,
            "id": 923,
            "updated_by": "abc",
            "deleted_at": None,
            "run_context": "local",
            "created_by": "xxx",
            "code_addr": None,
            "project_id": 3481,
            "model_id": "upgrade_test",
            "model_config_template": {
                "training_when_serving": False,
                "args": {
                    "node_code_node_643f7b": {
                        "index": 0,
                        "model_node_name": "代码",
                        "node_en_name": "code_node",
                        "description": "代码编辑节点， 用户可以通过写python代码实现自己的training(训练)、" "serving(应用)或transform(转换)逻辑",
                        "tags": [],
                        "node_runner_type": "serving_training",
                        "node_zh_name": "代码",
                        "output_fields": [
                            {
                                "field": "AGE",
                                "type": "double",
                                "description": "1940年前建成自用单位比例",
                            },
                            {
                                "field": "timestamp",
                                "type": "int",
                                "description": "timestamp",
                            },
                        ],
                        "other_training_info": None,
                        "custom_node_id": "node_code_node_a73dc2",
                        "use_other_training": False,
                        "node_type": "data_preparing",
                        "model_node_id": "node_code_node_643f7b",
                        "is_generalizable": True,
                        "children_model_node_ids": ["node_output_node_1fa807"],
                        "node_args": {
                            "has_training": {
                                "default_value": False,
                                "arg_type": "boolean",
                                "node_en_name": "code_node",
                                "description": "训练应用模式——会依次执行代码中实现的training和serving函数\n" "转换模式——针对验证集执行transform函数",
                                "is_output_field": False,
                                "is_advance_arg": False,
                                "created_at": "2017-09-13 09:51:44",
                                "updated_at": "2017-09-13 09:51:44",
                                "value": False,
                                "has_custom_performance": True,
                                "arg_en_name": "has_training",
                                "output_field_type": None,
                                "used_by": "developer",
                                "arg_index": 2,
                                "properties": {"is_required": True},
                                "arg_zh_name": "代码运行模式",
                            },
                            "run_context": {
                                "default_value": "local",
                                "arg_type": "string",
                                "node_en_name": "code_node",
                                "description": "如果运行环境是LOCAL， 则输入的数据格式是 pandas DataFrame,"
                                "如果运行环境是SPARK, 则输入的数据格式是 spark DataFrame;",
                                "is_output_field": False,
                                "is_advance_arg": False,
                                "created_at": "2017-09-13 10:23:29",
                                "updated_at": "2017-09-13 10:23:29",
                                "value": "local",
                                "has_custom_performance": False,
                                "arg_en_name": "run_context",
                                "output_field_type": None,
                                "used_by": "developer",
                                "arg_index": 1,
                                "properties": {
                                    "is_required": True,
                                    "optional": ["local", "spark"],
                                },
                                "arg_zh_name": "代码运行环境",
                            },
                            "max_process_groups": {
                                "default_value": -1,
                                "arg_type": "int",
                                "node_en_name": "code_node",
                                "description": "当数据时分组的时候，设置处理的最大分组数，可以解决使用全部分组数据处理过慢。" "（-1为使用全部分组）",
                                "is_output_field": False,
                                "is_advance_arg": True,
                                "created_at": "2017-11-13 12:15:50",
                                "updated_at": "2017-11-13 12:15:50",
                                "value": -1,
                                "has_custom_performance": False,
                                "arg_en_name": "max_process_groups",
                                "output_field_type": None,
                                "used_by": "developer",
                                "arg_index": 6,
                                "properties": {"is_required": False},
                                "arg_zh_name": "最大处理分组数",
                            },
                            "custom_args": {
                                "default_value": [],
                                "arg_type": "json",
                                "node_en_name": "code_node",
                                "description": "自定义参数。模型应用时，该代码节点需要从用户端拿到的配置参数，" "需要模型开发者填写每个参数的英文名，中文名，类型，默认值，描述",
                                "is_output_field": False,
                                "is_advance_arg": False,
                                "created_at": "2017-11-23 04:01:22",
                                "updated_at": "2017-11-23 04:01:22",
                                "value": [],
                                "has_custom_performance": True,
                                "arg_en_name": "custom_args",
                                "output_field_type": None,
                                "used_by": "developer",
                                "arg_index": 7,
                                "properties": {"is_required": False},
                                "arg_zh_name": "自定义参数",
                            },
                            "react_sample_dbs": {
                                "default_value": None,
                                "arg_type": "json",
                                "node_en_name": "code_node",
                                "description": "用户可以在代码节点中访问使用的样本库，可以配置多个，" "用户系统提供的接口使用访问相应样本库的数据。",
                                "is_output_field": False,
                                "is_advance_arg": True,
                                "created_at": "2018-06-07 22:09:24",
                                "updated_at": "2018-06-07 22:09:24",
                                "value": None,
                                "has_custom_performance": True,
                                "arg_en_name": "react_sample_dbs",
                                "output_field_type": None,
                                "used_by": "developer",
                                "arg_index": 8,
                                "properties": {"is_required": False},
                                "arg_zh_name": "代码可访问样本库",
                            },
                            "new_fields": {
                                "default_value": [],
                                "arg_type": "json",
                                "node_en_name": "code_node",
                                "description": "代码处理完成输入的DataFrame之后， 返回的DataFrame中新增的字段",
                                "is_output_field": False,
                                "is_advance_arg": False,
                                "created_at": "2017-09-13 10:29:12",
                                "updated_at": "2017-09-13 10:29:12",
                                "value": [
                                    {
                                        "field": "timestamp",
                                        "type": "int",
                                        "description": "timestamp",
                                    }
                                ],
                                "has_custom_performance": True,
                                "arg_en_name": "new_fields",
                                "output_field_type": None,
                                "used_by": "developer",
                                "arg_index": 4,
                                "properties": {"is_required": False},
                                "arg_zh_name": "新增字段",
                            },
                            "source_code": {
                                "default_value": '"""\n    training 训练应用模式下, 在模型训练的时候执行的函数,\n    '
                                "serving 训练应用模式下, 在模型应用的时候执行的函数,\n    "
                                "transform 转换模式下, 在模型进行转换时执行的函数;\n\n    "
                                "影响代码节点执行逻辑的参数有两个:\n        "
                                "节点运行模式:\n            "
                                "训练并验证(默认): 节点用training(transform)函数执行训练集数据, "
                                "用serving(transform)函数执行验证集数据\n            "
                                "仅验证: 节点仅用training(transform)函数执行训练集数据;\n            "
                                "仅训练: 节点仅用serving(transform)函数执行验证集数据;\n        "
                                "代码运行模式:\n            "
                                "训练应用模式: 需实现training和serving函数, "
                                "serving函数可使用training函数训练得到的模型\n            "
                                "转换模式: 需实现transform函数, 可分别对训练集或者验证集进行数据转换\n\n    "
                                "注意:\n        1 由于training和serving的调度周期存在差异,\n            "
                                "所以二者并不能共享代码文件中定义的全局变量;\n        "
                                "2 training 和 serving "
                                "唯一的交互是training训练得到的结果(model),\n            "
                                "serving函数可以使用;\n\n    常用库import:\n        "
                                "import pandas as pd\n        import numpy as np\n        "
                                "from bkdata.spark_util import get_spark_content, "
                                "get_spark_sql_content\n        spark_content = "
                                "get_spark_content(app_name='test_content')\n        "
                                "spark_sql_content = "
                                'get_spark_sql_content(app_name=\'test_sql_content\')\n"""\n\n'
                                'def training(args, df):\n    """\n        参数:\n            '
                                "args: 在节点配置页面指定的模型参数；\n            df: 输入数据, "
                                "如果运行环境是LOCAL， 则是 pandas DataFrame,\n                "
                                "如果运行环境是SPARK, 则是 spark DataFrame;\n\n        "
                                "返回：\n            "
                                "df: 处理之后的ＤataFrame, 要求和输入的df保持同一类型;\n            "
                                "model: 模型训练的结果, 该结果会被序列化之后保存起来,\n                "
                                '当执行serving函数的时候, 会被反序列化传给serving;\n    """\n    raise '
                                'NotImplementedError("Training function is not implemented.")\n\n\n'
                                'def serving(args, df, trained_result=None):\n    """\n        '
                                "参数:\n            args: 在节点配置页面指定的模型参数；\n            "
                                "df: 输入数据, 如果运行环境是LOCAL， "
                                "则是 pandas DataFrame,\n                "
                                "如果运行环境是SPARK, 则是 spark DataFrame;\n            "
                                "trained_result: 模型训练的结果, 即training函数返回的model；\n\n        "
                                "返回：\n            "
                                'df: 处理之后的ＤataFrame, 要求和输入的df保持同一类型;\n    """\n    '
                                "raise "
                                'NotImplementedError("Serving function is not implemented.")\n\n\n'
                                'def transform(args, df):\n    """\n        参数:\n            '
                                "args: 在节点配置页面指定的模型参数；\n            df: 输入数据, "
                                "如果运行环境是LOCAL， 则是 pandas DataFrame,\n                "
                                "如果运行环境是SPARK, 则是 spark DataFrame;\n\n        "
                                "返回：\n            df: 处理之后的ＤataFrame, "
                                '要求和输入的df保持同一类型;\n    """\n    '
                                'raise NotImplementedError("Transform function is not implemented.")',
                                "arg_type": "string",
                                "node_en_name": "code_node",
                                "description": "需要编写的源代码",
                                "is_output_field": False,
                                "is_advance_arg": False,
                                "created_at": "2017-09-13 10:25:24",
                                "updated_at": "2017-09-13 10:25:24",
                                "value": "xxx",
                                "has_custom_performance": True,
                                "arg_en_name": "source_code",
                                "output_field_type": None,
                                "used_by": "developer",
                                "arg_index": 3,
                                "properties": {"is_required": True},
                                "arg_zh_name": "源代码",
                            },
                            "access_null_input": {
                                "default_value": False,
                                "arg_type": "boolean",
                                "node_en_name": "code_node",
                                "description": "是否接受Null值作为此代码节点的输入，默认情况下， 当输入数据为Null时，"
                                "会跳过该节点的执行逻辑，\n如果该值为True， "
                                "则开发者需要在模型中处理输入为Null情况。",
                                "is_output_field": False,
                                "is_advance_arg": True,
                                "created_at": "2017-10-29 06:09:55",
                                "updated_at": "2017-10-29 06:09:55",
                                "value": False,
                                "has_custom_performance": False,
                                "arg_en_name": "access_null_input",
                                "output_field_type": None,
                                "used_by": "developer",
                                "arg_index": 5,
                                "properties": {"is_required": False},
                                "arg_zh_name": "是否接受NULL值输入",
                            },
                        },
                        "input_source_nums": 1,
                        "parent_model_node_ids": ["node_input_node_7aaeda"],
                        "cur_context": "any",
                        "node_graph_config": {
                            "status": "configured",
                            "model_id": "upgrade_test",
                            "project_id": 3481,
                            "model_status": "building",
                            "name": "代码",
                            "model_version_id": 16,
                            "title": "",
                            "auto": False,
                            "created_at": "2018-08-28 10:18:14",
                            "component": "code_node",
                            "updated_at": "2018-08-28 10:20:04",
                            "id": "node_code_node_643f7b",
                            "y": 190,
                            "x": 309,
                            "session_key": "<KEY>",
                            "type": "model-node",
                            "model_name": "升级测试模型",
                        },
                    }
                },
                "is_serving_scheduler_paras_set": False,
                "is_training_scheduler_paras_set": False,
                "output": {
                    "node_output_node_1fa807": {
                        "index": 0,
                        "model_node_name": "数据输出",
                        "node_en_name": "output_node",
                        "description": "数据输出节点, 输出为Result Table表",
                        "tags": [],
                        "node_runner_type": "serving_training",
                        "node_zh_name": "数据输出",
                        "output_fields": [
                            {
                                "field": "AGE",
                                "type": "double",
                                "description": "1940年前建成自用单位比例",
                            },
                            {
                                "field": "timestamp",
                                "type": "int",
                                "description": "timestamp",
                            },
                        ],
                        "other_training_info": None,
                        "custom_node_id": "node_output_node_9b981a",
                        "use_other_training": False,
                        "node_type": "data",
                        "model_node_id": "node_output_node_1fa807",
                        "is_generalizable": True,
                        "children_model_node_ids": [],
                        "node_args": {
                            "storages_args": {
                                "default_value": None,
                                "arg_type": "json",
                                "node_en_name": "output_node",
                                "description": "存储参数",
                                "is_output_field": False,
                                "is_advance_arg": False,
                                "created_at": "2016-10-18 17:07:31",
                                "updated_at": "2018-04-05 00:12:07",
                                "value": None,
                                "has_custom_performance": False,
                                "arg_en_name": "storages_args",
                                "output_field_type": None,
                                "used_by": "user",
                                "arg_index": 4,
                                "properties": {"is_required": False},
                                "arg_zh_name": "存储参数",
                            },
                            "output_group_info": {
                                "default_value": False,
                                "arg_type": "boolean",
                                "node_en_name": "output_node",
                                "description": "业务ID",
                                "is_output_field": False,
                                "is_advance_arg": False,
                                "created_at": "2018-06-07 22:12:16",
                                "updated_at": "2018-06-07 22:12:16",
                                "value": False,
                                "has_custom_performance": False,
                                "arg_en_name": "output_group_info",
                                "output_field_type": None,
                                "used_by": "developer",
                                "arg_index": 1,
                                "properties": {"is_required": False},
                                "arg_zh_name": "是否输出分组信息",
                            },
                            "table_zh_name": {
                                "default_value": None,
                                "arg_type": "string",
                                "node_en_name": "output_node",
                                "description": "输出数据使用的中文表名",
                                "is_output_field": False,
                                "is_advance_arg": False,
                                "created_at": "2018-06-07 22:10:53",
                                "updated_at": "2018-06-07 22:10:53",
                                "value": None,
                                "has_custom_performance": False,
                                "arg_en_name": "table_zh_name",
                                "output_field_type": None,
                                "used_by": "user",
                                "arg_index": 6,
                                "properties": {"is_required": False},
                                "arg_zh_name": "输出中文名",
                            },
                            "table_name": {
                                "default_value": None,
                                "arg_type": "string",
                                "node_en_name": "output_node",
                                "description": "输出数据使用的表名,以Result Table为输出目标",
                                "is_output_field": False,
                                "is_advance_arg": False,
                                "created_at": "2016-10-18 17:07:31",
                                "updated_at": "2018-04-05 00:12:07",
                                "value": None,
                                "has_custom_performance": False,
                                "arg_en_name": "table_name",
                                "output_field_type": None,
                                "used_by": "user",
                                "arg_index": 5,
                                "properties": {"is_required": False},
                                "arg_zh_name": "输出表",
                            },
                            "biz_id": {
                                "default_value": None,
                                "arg_type": "int",
                                "node_en_name": "output_node",
                                "description": "业务ID",
                                "is_output_field": False,
                                "is_advance_arg": False,
                                "created_at": "2016-10-18 17:07:31",
                                "updated_at": "2018-04-05 00:12:07",
                                "value": None,
                                "has_custom_performance": False,
                                "arg_en_name": "biz_id",
                                "output_field_type": None,
                                "used_by": "user",
                                "arg_index": 2,
                                "properties": {"is_required": False},
                                "arg_zh_name": "业务ID",
                            },
                            "project_id": {
                                "default_value": None,
                                "arg_type": "int",
                                "node_en_name": "output_node",
                                "description": "项目ID",
                                "is_output_field": False,
                                "is_advance_arg": False,
                                "created_at": "2016-10-18 17:07:31",
                                "updated_at": "2018-04-05 00:12:07",
                                "value": None,
                                "has_custom_performance": False,
                                "arg_en_name": "project_id",
                                "output_field_type": None,
                                "used_by": "user",
                                "arg_index": 3,
                                "properties": {"is_required": False},
                                "arg_zh_name": "项目ID",
                            },
                        },
                        "input_source_nums": 1,
                        "parent_model_node_ids": ["node_code_node_643f7b"],
                        "cur_context": "any",
                        "node_graph_config": {
                            "status": "configured",
                            "model_id": "upgrade_test",
                            "project_id": 3481,
                            "model_status": "building",
                            "name": "数据输出",
                            "model_version_id": 16,
                            "title": "",
                            "auto": False,
                            "created_at": "2018-08-28 10:18:14",
                            "component": "output_node",
                            "updated_at": "2018-08-28 10:20:04",
                            "id": "node_output_node_1fa807",
                            "y": 221,
                            "x": 607,
                            "session_key": "<KEY>",
                            "type": "model-node",
                            "model_name": "升级测试模型",
                        },
                    }
                },
                "training_scheduler_params": {"period": None, "first_run_time": None},
                "input": {
                    "node_input_node_7aaeda": {
                        "index": 0,
                        "model_node_name": "新版输入V2",
                        "node_en_name": "input_node_v2",
                        "description": "数据输入节点, 输入为Result Table表",
                        "tags": [],
                        "node_runner_type": "serving_training",
                        "node_zh_name": "数据输入V2",
                        "output_fields": [
                            {
                                "field": "AGE",
                                "type": "double",
                                "description": "1940年前建成自用单位比例",
                            }
                        ],
                        "other_training_info": None,
                        "custom_node_id": "node_input_node_v2_0d0c9a",
                        "use_other_training": False,
                        "node_type": "data",
                        "model_node_id": "node_input_node_7aaeda",
                        "is_generalizable": True,
                        "children_model_node_ids": ["node_code_node_643f7b"],
                        "node_args": {
                            "building_sample_db": {
                                "default_value": {
                                    "ts_properties": {
                                        "ts_agg": "last",
                                        "ts_period": None,
                                        "ts_depend": None,
                                        "ts_agg_orient": "up",
                                        "ts_field": None,
                                        "ts_freq": None,
                                    },
                                    "group_fields": [],
                                },
                                "arg_type": "json",
                                "node_en_name": "input_node_v2",
                                "used_by": "developer",
                                "value": {
                                    "ts_properties": {
                                        "ts_agg": "last",
                                        "ts_period": None,
                                        "ts_depend": None,
                                        "ts_agg_orient": "up",
                                        "ts_field": None,
                                        "ts_freq": None,
                                    },
                                    "group_fields": [],
                                },
                                "arg_en_name": "building_sample_db",
                                "is_advance_arg": False,
                                "properties": None,
                            },
                            "group_fields": {
                                "default_value": None,
                                "arg_type": "list",
                                "node_en_name": "input_node_v2",
                                "description": "分组字段列表， 用于将数据分为多个数据集",
                                "is_output_field": False,
                                "arg_index": 12,
                                "created_at": "2018-04-12 20:17:11",
                                "arg_en_name": "group_fields",
                                "updated_at": "2018-04-12 20:17:11",
                                "value": None,
                                "properties": {
                                    "source": "result_table",
                                    "list": "field",
                                },
                                "has_custom_performance": False,
                                "output_field_type": None,
                                "is_advance_arg": False,
                                "used_by": "user",
                                "arg_zh_name": "分组字段",
                            },
                            "serving_fields_mapping": {
                                "default_value": None,
                                "arg_type": "json",
                                "node_en_name": "input_node_v2",
                                "description": "验证集字段映射， 用于验证集合不是从训练集样本库切分出来的情况",
                                "is_output_field": False,
                                "arg_index": 11,
                                "created_at": "2018-04-12 20:15:51",
                                "arg_en_name": "serving_fields_mapping",
                                "updated_at": "2018-04-12 20:15:51",
                                "value": None,
                                "properties": {"depend": {"test_data_radio": 0}},
                                "has_custom_performance": False,
                                "output_field_type": None,
                                "is_advance_arg": False,
                                "used_by": "both",
                                "arg_zh_name": "字段映射",
                            },
                            "data_start_time": {
                                "default_value": "-7d",
                                "arg_type": "time",
                                "node_en_name": "input_node_v2",
                                "description": "样本数据的开始时间, 默认格式:'2016-10-17 23:53:49', "
                                "可以使用:'now'/'-1d'/'-7d'/'-1h'/'-48h'等描述方式, "
                                "只有当节点的serving方式是offline的时候, 此参数有效",
                                "is_output_field": False,
                                "arg_index": 9,
                                "created_at": "2018-04-12 20:14:23",
                                "arg_en_name": "data_start_time",
                                "updated_at": "2018-04-12 20:14:23",
                                "value": "-7d",
                                "properties": None,
                                "has_custom_performance": False,
                                "output_field_type": None,
                                "is_advance_arg": False,
                                "used_by": "user",
                                "arg_zh_name": "输入数据开始时间",
                            },
                            "serving_use_fields": {
                                "default_value": None,
                                "arg_type": "list",
                                "node_en_name": "input_node_v2",
                                "description": "模型执行 serving 的时候， 输入数据必须提供的字段",
                                "is_output_field": False,
                                "arg_index": 1,
                                "created_at": "2018-04-12 20:11:51",
                                "arg_en_name": "serving_use_fields",
                                "updated_at": "2018-04-12 20:11:51",
                                "value": ["AGE", "AGE"],
                                "properties": {"list": "field"},
                                "has_custom_performance": False,
                                "output_field_type": None,
                                "is_advance_arg": False,
                                "used_by": "developer",
                                "arg_zh_name": "模型必须字段",
                            },
                            "is_training_serving_same_source": {
                                "default_value": {
                                    "is_training_serving_same_source": False,
                                    "sample_start_time": "",
                                    "sample_end_time": "",
                                },
                                "arg_type": "json",
                                "node_en_name": "input_node_v2",
                                "description": "训练数据和应用数据来自相同的结果表，\r\n如果模型开发者把此项置为True，\r\n"
                                "则应用改模型的人只需要选择一个RT表作为输入， \r\n"
                                "而不用同时选择样本库和应用数据输入表。\r\n如果选择了此项，"
                                "则在固定应用配置参数中是否选择sample_db_name无效",
                                "is_output_field": False,
                                "arg_index": 16,
                                "created_at": "2018-04-12 20:16:18",
                                "arg_en_name": "is_training_serving_same_source",
                                "updated_at": "2018-04-12 20:16:18",
                                "value": {
                                    "is_training_serving_same_source": True,
                                    "sample_start_time": "-1d",
                                    "sample_end_time": "now",
                                },
                                "properties": None,
                                "has_custom_performance": False,
                                "output_field_type": None,
                                "is_advance_arg": True,
                                "used_by": "developer",
                                "arg_zh_name": "训练和应用数据源相同",
                            },
                            "ts_depend": {
                                "default_value": None,
                                "arg_type": "time",
                                "node_en_name": "input_node_v2",
                                "description": "用于时间序列数据，时序数据在特征提取转换等处理时需要用到相关的历史数据，" "参数用于指定依赖历史数据的长度",
                                "is_output_field": False,
                                "arg_index": 3,
                                "created_at": "2018-04-12 20:12:35",
                                "arg_en_name": "ts_depend",
                                "updated_at": "2018-04-12 20:12:35",
                                "value": None,
                                "properties": None,
                                "is_dynamic": True,
                                "has_custom_performance": False,
                                "output_field_type": None,
                                "is_advance_arg": True,
                                "used_by": "developer",
                                "arg_zh_name": "时序数据历史依赖",
                            },
                            "label_field": {
                                "default_value": None,
                                "arg_type": "field",
                                "node_en_name": "input_node_v2",
                                "description": "训练数据的标签字段",
                                "is_output_field": False,
                                "arg_index": 2,
                                "created_at": "2018-04-12 20:12:05",
                                "arg_en_name": "label_field",
                                "updated_at": "2018-04-12 20:12:05",
                                "value": "AGE",
                                "properties": {},
                                "has_custom_performance": False,
                                "output_field_type": None,
                                "is_advance_arg": False,
                                "used_by": "developer",
                                "arg_zh_name": "标签字段",
                            },
                            "sample_db_name": {
                                "default_value": None,
                                "arg_type": "string",
                                "node_en_name": "input_node_v2",
                                "description": "样本库， 用于模型训练的输入数据",
                                "is_output_field": False,
                                "arg_index": 0,
                                "created_at": "2018-04-12 20:11:37",
                                "arg_en_name": "sample_db_name",
                                "updated_at": "2018-04-12 20:11:37",
                                "value": None,
                                "properties": {"string": "sample_db"},
                                "has_custom_performance": False,
                                "output_field_type": None,
                                "is_advance_arg": False,
                                "used_by": "both",
                                "arg_zh_name": "样本库",
                            },
                            "training_fields_mapping": {
                                "default_value": None,
                                "arg_type": "json",
                                "node_en_name": "input_node_v2",
                                "description": "训练数据字段映射， 用于验证集合不是从训练集样本库切分出来的情况",
                                "is_output_field": False,
                                "arg_index": 4,
                                "created_at": "2018-04-12 20:19:09",
                                "arg_en_name": "training_fields_mapping",
                                "updated_at": "2018-04-12 20:19:09",
                                "value": None,
                                "properties": None,
                                "has_custom_performance": False,
                                "output_field_type": None,
                                "is_advance_arg": False,
                                "used_by": "user",
                                "arg_zh_name": "字段映射",
                            },
                            "data_end_time": {
                                "default_value": "now",
                                "arg_type": "time",
                                "node_en_name": "input_node_v2",
                                "description": "样本数据的结束时间, 默认格式:'2016-10-17 23:53:49', "
                                "可以使用:'now'/'-1d'/'-7d'/'-1h'/'-48h'等描述方式,"
                                "只有当节点的serving方式是offline的时候, 此参数有效",
                                "is_output_field": False,
                                "arg_index": 10,
                                "created_at": "2018-04-12 20:15:07",
                                "arg_en_name": "data_end_time",
                                "updated_at": "2018-04-12 20:15:07",
                                "value": "now",
                                "properties": None,
                                "has_custom_performance": False,
                                "output_field_type": None,
                                "is_advance_arg": False,
                                "used_by": "user",
                                "arg_zh_name": "输入数据结束时间",
                            },
                            "evaluate_sample_db_name": {
                                "default_value": None,
                                "arg_type": "string",
                                "node_en_name": "input_node_v2",
                                "description": "验证样本库， 用于模型验证的输入数据",
                                "is_output_field": False,
                                "arg_index": 6,
                                "created_at": "2018-04-12 20:20:55",
                                "arg_en_name": "evaluate_sample_db_name",
                                "updated_at": "2018-04-12 20:20:55",
                                "value": None,
                                "properties": {
                                    "depend": {"test_data_radio": 0},
                                    "string": "sample_db",
                                },
                                "has_custom_performance": False,
                                "output_field_type": None,
                                "is_advance_arg": False,
                                "used_by": "developer",
                                "arg_zh_name": "验证样本库",
                            },
                            "test_data_radio": {
                                "default_value": 0,
                                "arg_type": "float",
                                "node_en_name": "input_node_v2",
                                "description": "测试数据在样本库中的占比， 样本库的数据会被以此比例分割为两部分，" "训练集以及测试集",
                                "is_output_field": False,
                                "arg_index": 5,
                                "created_at": "2018-04-12 20:13:45",
                                "arg_en_name": "test_data_radio",
                                "updated_at": "2018-04-12 20:13:45",
                                "value": 0.5,
                                "properties": {"performance": "slider"},
                                "has_custom_performance": False,
                                "output_field_type": None,
                                "is_advance_arg": False,
                                "used_by": "developer",
                                "arg_zh_name": "验证集数据来源",
                            },
                            "input_result_table": {
                                "default_value": None,
                                "arg_type": "string",
                                "node_en_name": "input_node_v2",
                                "description": "输入数据,以Result Table为输入源",
                                "is_output_field": False,
                                "arg_index": 8,
                                "created_at": "2018-04-12 20:13:23",
                                "arg_en_name": "input_result_table",
                                "updated_at": "2018-04-12 20:13:23",
                                "value": None,
                                "properties": {"string": "result_table"},
                                "has_custom_performance": False,
                                "output_field_type": None,
                                "is_advance_arg": False,
                                "used_by": "user",
                                "arg_zh_name": "输入表",
                            },
                        },
                        "input_source_nums": 0,
                        "parent_model_node_ids": [],
                        "cur_context": "any",
                        "node_graph_config": {
                            "status": "configured",
                            "model_id": "upgrade_test",
                            "session_key": "13909da4cdd442569d5e21d7ee5df5b0",
                            "model_status": "building",
                            "name": "新版输入V2",
                            "model_version_id": 15,
                            "title": "",
                            "auto": False,
                            "created_at": "2018-08-28 10:04:46",
                            "component": "input_node_v2",
                            "updated_at": None,
                            "created_by": "abc",
                            "model_name": "升级测试模型",
                            "version_description": "new test",
                            "y": 166,
                            "x": 116,
                            "project_id": 3481,
                            "type": "model-input",
                            "id": "node_input_node_7aaeda",
                        },
                    }
                },
                "serving_scheduler_params": {
                    "serving_mode": None,
                    "period": None,
                    "first_run_time": None,
                },
            },
            "description": "升级测试模型",
            "model_alias": None,
            "scene_name": None,
            "biz_id": 0,
            "is_public": False,
            "is_latest": True,
            "properties": {},
            "is_deleted": False,
            "created_at": "2018-08-28 10:36:43",
            "model_name": "升级测试模型",
            "model_type": "flow",
            "version_description": "16",
            "template_id": None,
            "serving_mode": "realtime",
        }
        return self.success_response(data)
# -*- coding: utf-8 -*- Tencent is pleased to support the open source community by making BK-BASE 蓝鲸基础平台 available.  Copyright (C) 2021 THL A29 Limited, a Tencent company.  All rights reserved.  BK-BASE 蓝鲸基础平台 is licensed under the MIT License.  License for BK-BASE 蓝鲸基础平台: -------------------------------------------------------------------- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \n    training 训练应用模式下, 在模型训练的时候执行的函数,\n    '                                 "serving 训练应用模式下, 在模型应用的时候执行的函数,\n    "                                 "transform 转换模式下, 在模型进行转换时执行的函数;\n\n    "                                 "影响代码节点执行逻辑的参数有两个:\n        "                                 "节点运行模式:\n            "                                 "训练并验证(默认): 节点用training(transform)函数执行训练集数据, "                                 "用serving(transform)函数执行验证集数据\n            "                                 "仅验证: 节点仅用training(transform)函数执行训练集数据;\n            "                                 "仅训练: 节点仅用serving(transform)函数执行验证集数据;\n        "                                 "代码运行模式:\n            "                                 "训练应用模式: 需实现training和serving函数, "                                 "serving函数可使用training函数训练得到的模型\n            "                                 "转换模式: 需实现transform函数, 可分别对训练集或者验证集进行数据转换\n\n    "                                 "注意:\n        1 由于training和serving的调度周期存在差异,\n            "                                 "所以二者并不能共享代码文件中定义的全局变量;\n        "                                 "2 training 和 serving "                                 "唯一的交互是training训练得到的结果(model),\n            "                                 "serving函数可以使用;\n\n    常用库import:\n        "                                 "import pandas as pd\n        import numpy as np\n        "                                 "from bkdata.spark_util import get_spark_content, "                                 "get_spark_sql_content\n        spark_content = "                                 "get_spark_content(app_name='test_content')\n        "                                 "spark_sql_content = "                                 'get_spark_sql_content(app_name=\'test_sql_content\')\n \n        参数:\n            '                                 "args: 在节点配置页面指定的模型参数；\n            df: 输入数据, "                                 "如果运行环境是LOCAL， 则是 pandas DataFrame,\n                "                                 "如果运行环境是SPARK, 则是 spark DataFrame;\n\n        "                                 "返回：\n            "                                 "df: 处理之后的ＤataFrame, 要求和输入的df保持同一类型;\n            "                                 "model: 模型训练的结果, 该结果会被序列化之后保存起来,\n                "                                 '当执行serving函数的时候, 会被反序列化传给serving;\n \n        '                                 "参数:\n            args: 在节点配置页面指定的模型参数；\n            "                                 "df: 输入数据, 如果运行环境是LOCAL， "                                 "则是 pandas DataFrame,\n                "                                 "如果运行环境是SPARK, 则是 spark DataFrame;\n            "                                 "trained_result: 模型训练的结果, 即training函数返回的model；\n\n        "                                 "返回：\n            "                                 'df: 处理之后的ＤataFrame, 要求和输入的df保持同一类型;\n \n        参数:\n            '                                 "args: 在节点配置页面指定的模型参数；\n            df: 输入数据, "                                 "如果运行环境是LOCAL， 则是 pandas DataFrame,\n                "                                 "如果运行环境是SPARK, 则是 spark DataFrame;\n\n        "                                 "返回：\n            df: 处理之后的ＤataFrame, "                                 '要求和输入的df保持同一类型;\n