component_base.py 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. #
  2. # Copyright 2019 The FATE Authors. All Rights Reserved.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. #
  16. import copy
  17. from pipeline.constant import ProviderType
  18. from pipeline.utils.logger import LOGGER
  19. class Component(object):
  20. __instance = {}
  21. def __init__(self, *args, **kwargs):
  22. LOGGER.debug(f"kwargs: {kwargs}")
  23. if "name" in kwargs:
  24. self._component_name = kwargs["name"]
  25. self.__party_instance = {}
  26. self._component_parameter_keywords = set(kwargs.keys())
  27. self._role_parameter_keywords = set()
  28. self._module_name = None
  29. self._component_param = {}
  30. self._provider = None # deprecated, to compatible with fate-1.7.0
  31. self._source_provider = None
  32. self._provider_version = None
  33. def __new__(cls, *args, **kwargs):
  34. if cls.__name__.lower() not in cls.__instance:
  35. cls.__instance[cls.__name__.lower()] = 0
  36. new_cls = object.__new__(cls)
  37. new_cls.set_name(cls.__instance[cls.__name__.lower()])
  38. cls.__instance[cls.__name__.lower()] += 1
  39. return new_cls
  40. def set_name(self, idx):
  41. self._component_name = self.__class__.__name__.lower() + "_" + str(idx)
  42. LOGGER.debug(f"enter set name func {self._component_name}")
  43. def reset_name(self, name):
  44. self._component_name = name
  45. @property
  46. def provider(self):
  47. return self._provider
  48. @provider.setter
  49. def provider(self, provider):
  50. self._provider = provider
  51. @property
  52. def source_provider(self):
  53. return self._source_provider
  54. @property
  55. def provider_version(self):
  56. return self._provider_version
  57. @provider_version.setter
  58. def provider_version(self, provider_version):
  59. self._provider_version = provider_version
  60. def get_party_instance(self, role="guest", party_id=None) -> 'Component':
  61. if role not in ["guest", "host", "arbiter"]:
  62. raise ValueError("Role should be one of guest/host/arbiter")
  63. if party_id is not None:
  64. if isinstance(party_id, list):
  65. for _id in party_id:
  66. if not isinstance(_id, int) or _id <= 0:
  67. raise ValueError("party id should be positive integer")
  68. elif not isinstance(party_id, int) or party_id <= 0:
  69. raise ValueError("party id should be positive integer")
  70. if role not in self.__party_instance:
  71. self.__party_instance[role] = {}
  72. self.__party_instance[role]["party"] = {}
  73. party_key = party_id
  74. if isinstance(party_id, list):
  75. party_key = "|".join(map(str, party_id))
  76. if party_key not in self.__party_instance[role]["party"]:
  77. self.__party_instance[role]["party"][party_key] = None
  78. if not self.__party_instance[role]["party"][party_key]:
  79. party_instance = copy.deepcopy(self)
  80. self._decrease_instance_count()
  81. self.__party_instance[role]["party"][party_key] = party_instance
  82. LOGGER.debug(f"enter init")
  83. return self.__party_instance[role]["party"][party_key]
  84. @classmethod
  85. def _decrease_instance_count(cls):
  86. cls.__instance[cls.__name__.lower()] -= 1
  87. LOGGER.debug(f"decrease instance count")
  88. @property
  89. def name(self):
  90. return self._component_name
  91. @property
  92. def module(self):
  93. return self._module_name
  94. def component_param(self, **kwargs):
  95. new_kwargs = copy.deepcopy(kwargs)
  96. for attr in self.__dict__:
  97. if attr in new_kwargs:
  98. setattr(self, attr, new_kwargs[attr])
  99. self._component_param[attr] = new_kwargs[attr]
  100. del new_kwargs[attr]
  101. for attr in new_kwargs:
  102. LOGGER.warning(f"key {attr}, value {new_kwargs[attr]} not use")
  103. self._role_parameter_keywords |= set(kwargs.keys())
  104. def get_component_param(self):
  105. return self._component_param
  106. def get_common_param_conf(self):
  107. """
  108. exclude_attr = ["_component_name", "__party_instance",
  109. "_component_parameter_keywords", "_role_parameter_keywords"]
  110. """
  111. common_param_conf = {}
  112. for attr in self.__dict__:
  113. if attr.startswith("_"):
  114. continue
  115. if attr in self._role_parameter_keywords:
  116. continue
  117. if attr not in self._component_parameter_keywords:
  118. continue
  119. common_param_conf[attr] = getattr(self, attr)
  120. return common_param_conf
  121. def get_role_param_conf(self, roles=None):
  122. role_param_conf = {}
  123. if not self.__party_instance:
  124. return role_param_conf
  125. for role in self.__party_instance:
  126. role_param_conf[role] = {}
  127. if None in self.__party_instance[role]["party"]:
  128. role_all_party_conf = self.__party_instance[role]["party"][None].get_component_param()
  129. if "all" not in role_param_conf:
  130. role_param_conf[role]["all"] = {}
  131. role_param_conf[role]["all"][self._component_name] = role_all_party_conf
  132. valid_partyids = roles.get(role)
  133. for party_id in self.__party_instance[role]["party"]:
  134. if not party_id:
  135. continue
  136. if isinstance(party_id, int):
  137. party_key = str(valid_partyids.index(party_id))
  138. else:
  139. party_list = list(map(int, party_id.split("|", -1)))
  140. party_key = "|".join(map(str, [valid_partyids.index(party) for party in party_list]))
  141. party_inst = self.__party_instance[role]["party"][party_id]
  142. if party_key not in role_param_conf:
  143. role_param_conf[role][party_key] = {}
  144. role_param_conf[role][party_key][self._component_name] = party_inst.get_component_param()
  145. # print ("role_param_conf {}".format(role_param_conf))
  146. LOGGER.debug(f"role_param_conf {role_param_conf}")
  147. return role_param_conf
  148. @classmethod
  149. def erase_component_base_param(cls, **kwargs):
  150. new_kwargs = copy.deepcopy(kwargs)
  151. if "name" in new_kwargs:
  152. del new_kwargs["name"]
  153. return new_kwargs
  154. def get_config(self, *args, **kwargs):
  155. """need to implement"""
  156. roles = kwargs["roles"]
  157. common_param_conf = self.get_common_param_conf()
  158. role_param_conf = self.get_role_param_conf(roles)
  159. conf = {}
  160. if common_param_conf:
  161. conf['common'] = {self._component_name: common_param_conf}
  162. if role_param_conf:
  163. conf["role"] = role_param_conf
  164. return conf
  165. def _get_all_party_instance(self):
  166. return self.__party_instance
  167. class FateComponent(Component):
  168. def __init__(self, *args, **kwargs):
  169. super(FateComponent, self).__init__(*args, **kwargs)
  170. self._source_provider = ProviderType.FATE
  171. class FateFlowComponent(Component):
  172. def __init__(self, *args, **kwargs):
  173. super(FateFlowComponent, self).__init__(*args, **kwargs)
  174. self._source_provider = ProviderType.FATE_FLOW
  175. class FateSqlComponent(Component):
  176. def __init__(self, *args, **kwargs):
  177. super(FateSqlComponent, self).__init__(*args, **kwargs)
  178. self._source_provider = ProviderType.FATE_SQL
  179. class PlaceHolder(object):
  180. pass