How to use hierarchy_properties method in Lemoncheesecake

Best Python code snippet using lemoncheesecake

templates.py

Source:templates.py Github

copy

Full Screen

1import abc2import textwrap3from simphony_metaparser.flags import NoDefault4from simphony_metaparser.utils import with_cuba_prefix, \5 cuba_key_to_property_name, without_cuba_prefix6from simphony_metatools import utils7class File(object):8 def __init__(self):9 self.imports = set()10 self.classes = []11 self.methods = []12 def render(self, out, indent_level=0):13 imports = set(self.imports)14 for cls in self.classes:15 for imp in cls.import_required():16 imports.add(imp)17 for imp in imports:18 imp.render(out, indent_level)19 for cls in self.classes:20 cls.render(out, indent_level)21 for meth in self.methods:22 meth.render(out, indent_level)23class ShortcutImport(object):24 IMPORT_PATHS = {25 'CUBA': 'from simphony.core.cuba import CUBA',26 'DataContainer': 'from simphony.core.data_container import DataContainer', # noqa27 'create_data_container': 'from simphony.core.data_container import create_data_container', # noqa28 'KEYWORDS': 'from simphony.core.keywords import KEYWORDS',29 'validation': 'from simphony.cuds import meta_validation',30 'uuid': 'import uuid',31 'Default': 'from simphony.core import Default # noqa'32 }33 def __init__(self, module_shortcut):34 self.module_shortcut = module_shortcut35 def render(self, out, indent_level=0):36 out.write(37 utils.indent(38 self._render_import(),39 indent_level40 )+'\n'41 )42 def _render_import(self):43 return self.IMPORT_PATHS[self.module_shortcut]44 def __hash__(self):45 return hash(self._render_import())46 def __eq__(self, other):47 return hash(other) == hash(self)48class MetaClassImport(object):49 def __init__(self, meta_class_name):50 self.meta_class_name = meta_class_name51 def render(self, out, indent_level=0):52 out.write(53 utils.indent(54 self._render_import(),55 indent_level56 ) + '\n'57 )58 def _render_import(self):59 return "from .{meta_class_module_name} import {meta_class_name}".format( # noqa60 meta_class_module_name=utils.meta_class_name_to_module_name( # noqa61 self.meta_class_name62 ),63 meta_class_name=self.meta_class_name64 )65 def __hash__(self):66 return hash(self._render_import())67 def __eq__(self, other):68 return hash(other) == hash(self)69class Class(object):70 def __init__(self,71 class_name,72 cuba_key,73 parent_class_name,74 hierarchy_properties,75 docstring=""):76 self.class_name = class_name77 self.cuba_key = cuba_key78 self.parent_class_name = parent_class_name79 self.hierarchy_properties = hierarchy_properties80 self.docstring = docstring81 self.methods = []82 self.properties = []83 def import_required(self):84 required = [ShortcutImport("Default")]85 if self.parent_class_name is not None:86 required += [87 MetaClassImport(self.parent_class_name)88 ]89 return required + sum(90 (prop.import_required() for prop in self.properties),91 [])92 def render(self, out, indent_level=0):93 parent_class_name = (self.parent_class_name94 if self.parent_class_name is not None95 else "object")96 s = "class {class_name}({parent_class_name}):\n".format(97 class_name=self.class_name,98 parent_class_name=parent_class_name,99 )100 s += utils.indent(utils.format_docstring(self.docstring))+'\n'101 s += utils.indent("cuba_key = {qualified_cuba_key}\n".format(102 qualified_cuba_key=with_cuba_prefix(self.cuba_key)))103 out.write(utils.indent(s, indent_level))104 out.write(utils.indent(self._render_init_method(),105 indent_level+1))106 out.write(utils.indent(self._render_supported_parameters(),107 indent_level+1))108 for method in self.methods:109 method.render(out, indent_level=indent_level+1)110 for prop in self.properties:111 prop.render(out, indent_level=indent_level+1)112 def _render_init_method(self):113 # We have various types of properties.114 # with/without default = optional/mandatory115 # reimplemented/not reimplemented.116 # We need to take care of the combinations117 # so that the init is well behaved118 mandatory, optional, pass_down = self._compute_init_args_info()119 init_args = []120 super_init_args = []121 for arg in mandatory:122 init_args.append("{}".format(arg))123 for arg in optional:124 init_args.append("{}=Default".format(arg))125 for arg in pass_down:126 super_init_args.append("{}={}".format(arg, arg))127 s = textwrap.dedent("""def __init__({init_args_str}):""".format(128 init_args_str=", ".join(init_args))+'\n'129 )130 s += utils.indent(textwrap.dedent("""super({class_name}, self).__init__({super_init_args_str})""".format( # noqa131 class_name=self.class_name,132 super_init_args_str=", ".join(super_init_args))133 ))+'\n'134 for prop in self.properties:135 if prop.reimplemented:136 continue137 if isinstance(prop, VariableProperty):138 s += utils.indent(139 textwrap.dedent(140 """self._init_{prop_name}({prop_name})""".format( # noqa141 prop_name=prop.name)))+'\n'142 else:143 s += utils.indent(144 textwrap.dedent(145 """self._init_{prop_name}()""".format(146 prop_name=prop.name)))+'\n'147 return s148 def _compute_init_args_info(self):149 hierarchy_mandatory = []150 hierarchy_optional = []151 pass_down = []152 for prop_group in self.hierarchy_properties:153 for prop in sorted(154 [p for p in prop_group if isinstance(p, VariableProperty)],155 key=lambda x: x.name):156 if (prop.name in hierarchy_mandatory or157 prop.name in hierarchy_optional):158 continue159 if prop.default is NoDefault:160 hierarchy_mandatory.append(prop.name)161 else:162 hierarchy_optional.append(prop.name)163 pass_down.append(prop.name)164 cur_class_mandatory = []165 cur_class_optional = []166 for prop in sorted(167 [p for p in self.properties168 if isinstance(p, VariableProperty)],169 key=lambda x: x.name):170 if (prop.name in hierarchy_mandatory and171 prop.default is not NoDefault):172 # A property that was mandatory now has a default.173 hierarchy_mandatory.remove(prop.name)174 cur_class_optional.append(prop.name)175 elif (prop.name in hierarchy_optional and176 prop.default is NoDefault):177 # A property that was optional has been reimplemented178 # without default179 hierarchy_optional.remove(prop.name)180 cur_class_mandatory.append(prop.name)181 else:182 if prop.default is NoDefault:183 cur_class_mandatory.append(prop.name)184 else:185 cur_class_optional.append(prop.name)186 return (['self'] +187 utils.deduplicate(cur_class_mandatory + hierarchy_mandatory),188 utils.deduplicate(cur_class_optional + hierarchy_optional),189 utils.deduplicate(pass_down))190 def _render_supported_parameters(self):191 params = []192 for prop in self.properties:193 if isinstance(prop, VariableProperty):194 params.append(prop.source_key)195 elif isinstance(prop, UIDProperty):196 params.append("CUBA.UID")197 s = textwrap.dedent("""198 @classmethod199 def supported_parameters(cls):200 try:201 base_params = super(202 {class_name},203 cls).supported_parameters()204 except AttributeError:205 base_params = ()206 return tuple(set(({params}) + base_params))207 """.format(208 class_name=self.class_name,209 params="".join([p+", " for p in params]))210 )211 return s212class MetaAPIMethods(object):213 """These methods go only in the base class (whose parent is empty)"""214 def render(self, out, indent_level=0):215 out.write(216 utils.indent(textwrap.dedent(217 """218 @classmethod219 def parents(cls):220 return tuple(221 c.cuba_key222 for c in cls.__mro__[1:]223 if hasattr(c, "cuba_key"))224 """),225 indent_level)226 )227class ABCProperty(object):228 """Describes a template for a generic python property.229 It's an abstract class. Derived classes must reimplement the230 appropriate methods for rendering"""231 __metaclass__ = abc.ABCMeta232 def __init__(self, name, default=NoDefault, docstring=""):233 self.name = name234 self.default = default235 self.docstring = docstring236 @abc.abstractmethod237 def import_required(self):238 """Must return the import required to make the property work,239 as a list of ShortcutImport or MetaClassImport"""240 @abc.abstractmethod241 def _render_init(self):242 """Renders the initialization routine. This is called243 by the class __init__ method.244 Must return a string containing the rendered data."""245 @abc.abstractmethod246 def _render_setter(self):247 """Renders the setter method.248 Must return a string containing the rendered data."""249 @abc.abstractmethod250 def _render_getter(self):251 """Renders the getter method.252 Must return a string containing the rendered data.253 """254 @abc.abstractmethod255 def _render_validation(self):256 """Renders the validation method.257 Must return a string containing the rendered data.258 """259 @abc.abstractmethod260 def _render_default(self):261 """Renders a routine that returns the appropriate default.262 Must return a string containing the rendered data.263 """264 pass265 def render(self, out, indent_level=0):266 """Triggers the rendering267 out: file-like268 Where to write the rendering269 indent_level: int270 used to indent the rendering of a given level amount.271 """272 s = self._render_init()273 s += self._render_getter()274 s += self._render_setter()275 s += self._render_validation()276 s += self._render_default()277 out.write(utils.indent(s, indent_level))278class FixedProperty(ABCProperty):279 """Describes a fixed property template."""280 def __init__(self, source_key, default, reimplemented):281 """Defines a fixed property"""282 super(FixedProperty, self).__init__(source_key, default)283 # This is the original name as it comes from the ontology tree.284 # the template "property name" is the actual name that goes in the285 # python code.286 self.source_key = source_key287 # True if the property is reimplemented on the base class, hence288 # its rendering must keep this into account for appropriate289 # initialization290 self.reimplemented = reimplemented291 def _render_init(self):292 if self.reimplemented:293 return ""294 return textwrap.dedent("""295 def _init_{name}(self):296 self._{name} = self._default_{name}() # noqa297 """).format(298 name=self.name)299 def _render_default(self):300 return textwrap.dedent("""301 def _default_{name}(self):302 return {default} # noqa303 """).format(name=self.name,304 default=utils.quoted_if_string(self.default))305 def _render_setter(self):306 return ""307 def _render_validation(self):308 return ""309 def _render_getter(self):310 if self.reimplemented:311 return ""312 return textwrap.dedent("""313 @property314 def {name}(self):315 return self._{name}316 """).format(name=self.name)317 def import_required(self):318 imp = []319 return imp320class VariableProperty(ABCProperty):321 """Describes a variable (CUBA) property template."""322 def import_required(self):323 imp = [ShortcutImport("Default")]324 imp += [ShortcutImport("validation")]325 if utils.is_cuba_key(self.default):326 imp.append(327 MetaClassImport(328 meta_class_name=utils.cuba_key_to_meta_class_name(329 self.default)330 )331 )332 elif isinstance(self.default, (list, tuple)):333 default = '{}'.format(self.default)334 if 'CUBA.' in default:335 for elem in self.default:336 if utils.is_cuba_key(elem):337 imp.append(338 MetaClassImport(339 meta_class_name=utils.cuba_key_to_meta_class_name(elem))) # noqa340 return imp341 def __init__(self, qual_cuba_key, default, shape, reimplemented):342 if shape is None:343 raise ValueError("shape cannot be None")344 self.source_key = qual_cuba_key345 prop_name = cuba_key_to_property_name(qual_cuba_key)346 super(VariableProperty, self).__init__(347 name=prop_name,348 default=default)349 self.shape = shape350 self.reimplemented = reimplemented351 def _render_init(self):352 return textwrap.dedent("""353 def _init_{name}(self, value):354 if value is Default:355 value = self._default_{name}()356 self.{name} = value357 """).format(name=self.name)358 def _render_setter(self):359 return textwrap.dedent("""360 @{prop_name}.setter361 def {prop_name}(self, value):362 value = self._validate_{prop_name}(value)363 self.data[{qual_cuba_key}] = value364 """).format(365 prop_name=self.name,366 qual_cuba_key=self.source_key)367 def _render_getter(self):368 return textwrap.dedent("""369 @property370 def {prop_name}(self):371 return self.data[{qual_cuba_key}]372 """).format(373 prop_name=self.name,374 qual_cuba_key=self.source_key)375 def _render_validation(self):376 cuba_key = without_cuba_prefix(self.source_key)377 if self.shape == [1]:378 return textwrap.dedent("""379 def _validate_{prop_name}(self, value):380 value = meta_validation.cast_data_type(value, '{cuba_key}')381 meta_validation.check_valid_shape(value, {shape}, '{cuba_key}')382 meta_validation.validate_cuba_keyword(value, '{cuba_key}')383 return value384 """.format(prop_name=self.name,385 cuba_key=cuba_key,386 shape=self.shape))387 else:388 return textwrap.dedent("""389 def _validate_{prop_name}(self, value):390 value = meta_validation.cast_data_type(value, '{cuba_key}')391 meta_validation.check_valid_shape(value, {shape}, '{cuba_key}')392 meta_validation.check_elements(value, {shape}, '{cuba_key}')393 return value394 """.format(prop_name=self.name,395 cuba_key=cuba_key,396 shape=self.shape))397 def _render_default(self):398 if self.default == NoDefault:399 return textwrap.dedent("""400 def _default_{name}(self):401 raise TypeError("No default for {name}")402 """).format(name=self.name)403 if utils.is_cuba_key(self.default):404 default = utils.cuba_key_to_instantiation(self.default)405 elif isinstance(self.default, (list, tuple)):406 default = '{}'.format(self.default)407 if 'CUBA.' in default:408 elements = []409 for elem in self.default:410 if utils.is_cuba_key(elem):411 elem = utils.cuba_key_to_instantiation(elem)412 elements.append(elem)413 default = '[' + ", ".join(elements) + ']'414 else:415 default = utils.quoted_if_string(self.default)416 return textwrap.dedent("""417 def _default_{name}(self):418 return {default}419 """).format(name=self.name,420 default=default)421class DataProperty(FixedProperty):422 """Special data property is handled slightly different.423 It is a fixed property, but the value does not come from424 a hardcoded value in its default."""425 def __init__(self):426 super(DataProperty, self).__init__("data", None, False)427 self.source_key = "data"428 def import_required(self):429 return [ShortcutImport("DataContainer")]430 def _render_getter(self):431 return textwrap.dedent("""432 @property433 def data(self):434 return self._data435 """)436 def _render_setter(self):437 return textwrap.dedent("""438 @data.setter439 def data(self, new_data):440 self._data = DataContainer(new_data)441 """)442 def _render_init(self):443 return textwrap.dedent("""444 def _init_data(self):445 self._data = DataContainer()446 """)447 def _render_validation(self):448 return ""449 def _render_default(self):450 return ""451class UIDProperty(FixedProperty):452 """Special property that handles the special case of CUBA.UID.453 It behaves like a fixed property, but it has a CUBA qualified key.454 """455 def __init__(self):456 super(UIDProperty, self).__init__("uid", None, False)457 self.source_key = "uid"458 def import_required(self):459 return [ShortcutImport('uuid')]460 def _render_init(self):461 return textwrap.dedent("""462 def _init_uid(self):463 self.data[CUBA.UID] = uuid.uuid4()464 """)465 def _render_getter(self):466 return textwrap.dedent("""467 @property468 def uid(self):469 return self.data[CUBA.UID]470 """)471 def _render_setter(self):472 return ""473 def _render_validation(self):474 return ""475 def _render_default(self):...

Full Screen

Full Screen

HierarchyService.py

Source:HierarchyService.py Github

copy

Full Screen

1# -*- coding: utf-8 -*-2import json3from typing import Dict, Tuple, List, Optional4from requests import Response5from TM1py.Objects import Hierarchy, Element, ElementAttribute6from TM1py.Services.ElementService import ElementService7from TM1py.Services.ObjectService import ObjectService8from TM1py.Services.RestService import RestService9from TM1py.Services.SubsetService import SubsetService10from TM1py.Utils.Utils import case_and_space_insensitive_equals, format_url11class HierarchyService(ObjectService):12 """ Service to handle Object Updates for TM1 Hierarchies13 14 """15 # Tuple with TM1 Versions where Edges need to be created through TI, due to bug:16 # https://www.ibm.com/developerworks/community/forums/html/topic?id=75f2b99e-6961-4c71-9364-1d5e1e083eff17 EDGES_WORKAROUND_VERSIONS = ('11.0.002', '11.0.003', '11.1.000')18 def __init__(self, rest: RestService):19 super().__init__(rest)20 self.subsets = SubsetService(rest)21 self.elements = ElementService(rest)22 def create(self, hierarchy: Hierarchy, **kwargs):23 """ Create a hierarchy in an existing dimension24 :param hierarchy:25 :return:26 """27 url = format_url("/api/v1/Dimensions('{}')/Hierarchies", hierarchy.dimension_name)28 response = self._rest.POST(url, hierarchy.body, **kwargs)29 return response30 def get(self, dimension_name: str, hierarchy_name: str, **kwargs):31 """ get hierarchy32 :param dimension_name: name of the dimension33 :param hierarchy_name: name of the hierarchy34 :return:35 """36 url = format_url(37 "/api/v1/Dimensions('{}')/Hierarchies('{}')?$expand=Edges,Elements,ElementAttributes,Subsets,DefaultMember",38 dimension_name,39 hierarchy_name)40 response = self._rest.GET(url, **kwargs)41 return Hierarchy.from_dict(response.json())42 def get_all_names(self, dimension_name: str, **kwargs):43 """ get all names of existing Hierarchies in a dimension44 :param dimension_name:45 :return:46 """47 url = format_url("/api/v1/Dimensions('{}')/Hierarchies?$select=Name", dimension_name)48 response = self._rest.GET(url, **kwargs)49 return [hierarchy["Name"] for hierarchy in response.json()["value"]]50 def update(self, hierarchy: Hierarchy, **kwargs) -> List[Response]:51 """ update a hierarchy. It's a two step process: 52 1. Update Hierarchy53 2. Update Element-Attributes54 Function caters for Bug with Edge Creation:55 https://www.ibm.com/developerworks/community/forums/html/topic?id=75f2b99e-6961-4c71-9364-1d5e1e083eff56 :param hierarchy: instance of TM1py.Hierarchy57 :return: list of responses58 """59 # functions returns multiple responses60 responses = list()61 # 1. Update Hierarchy62 url = format_url("/api/v1/Dimensions('{}')/Hierarchies('{}')", hierarchy.dimension_name, hierarchy.name)63 # Workaround EDGES: Handle Issue, that Edges cant be created in one batch with the Hierarchy in certain versions64 hierarchy_body = hierarchy.body_as_dict65 if self.version[0:8] in self.EDGES_WORKAROUND_VERSIONS:66 del hierarchy_body["Edges"]67 responses.append(self._rest.PATCH(url, json.dumps(hierarchy_body), **kwargs))68 # 2. Update Attributes69 responses.append(self.update_element_attributes(hierarchy=hierarchy, **kwargs))70 # Workaround EDGES71 if self.version[0:8] in self.EDGES_WORKAROUND_VERSIONS:72 from TM1py.Services import ProcessService73 process_service = ProcessService(self._rest)74 ti_function = "HierarchyElementComponentAdd('{}', '{}', '{}', '{}', {});"75 ti_statements = [ti_function.format(hierarchy.dimension_name, hierarchy.name,76 edge[0],77 edge[1],78 hierarchy.edges[(edge[0], edge[1])])79 for edge80 in hierarchy.edges]81 responses.append(process_service.execute_ti_code(lines_prolog=ti_statements, **kwargs))82 return responses83 def exists(self, dimension_name: str, hierarchy_name: str, **kwargs) -> bool:84 """85 :param dimension_name: 86 :param hierarchy_name: 87 :return: 88 """89 url = format_url("/api/v1/Dimensions('{}')/Hierarchies('{}')", dimension_name, hierarchy_name)90 return self._exists(url, **kwargs)91 def delete(self, dimension_name: str, hierarchy_name: str, **kwargs) -> Response:92 url = format_url("/api/v1/Dimensions('{}')/Hierarchies('{}')", dimension_name, hierarchy_name)93 return self._rest.DELETE(url, **kwargs)94 def get_hierarchy_summary(self, dimension_name: str, hierarchy_name: str, **kwargs) -> Dict[str, int]:95 hierarchy_properties = ("Elements", "Edges", "ElementAttributes", "Members", "Levels")96 url = format_url(97 "/api/v1/Dimensions('{}')/Hierarchies('{}')?$expand=Edges/$count,Elements/$count,"98 "ElementAttributes/$count,Members/$count,Levels/$count&$select=Cardinality",99 dimension_name,100 hierarchy_name)101 hierary_summary_raw = self._rest.GET(url, **kwargs).json()102 return {hierarchy_property: hierary_summary_raw[hierarchy_property + "@odata.count"]103 for hierarchy_property104 in hierarchy_properties}105 def update_element_attributes(self, hierarchy: Hierarchy, **kwargs):106 """ Update the elementattributes of a hierarchy107 :param hierarchy: Instance of TM1py.Hierarchy108 :return:109 """110 # get existing attributes first111 element_attributes = self.elements.get_element_attributes(112 dimension_name=hierarchy.dimension_name,113 hierarchy_name=hierarchy.name,114 **kwargs)115 element_attribute_names = [ea.name for ea in element_attributes]116 # write ElementAttributes that don't already exist117 for element_attribute in hierarchy.element_attributes:118 if element_attribute not in element_attribute_names:119 self.elements.create_element_attribute(120 dimension_name=hierarchy.dimension_name,121 hierarchy_name=hierarchy.name,122 element_attribute=element_attribute,123 **kwargs)124 # delete attributes that are determined to be removed125 for element_attribute in element_attribute_names:126 if element_attribute not in hierarchy.element_attributes:127 self.elements.delete_element_attribute(128 dimension_name=hierarchy.dimension_name,129 hierarchy_name=hierarchy.name,130 element_attribute=element_attribute,131 **kwargs)132 def get_default_member(self, dimension_name: str, hierarchy_name: str = None, **kwargs) -> Optional[str]:133 """ Get the defined default_member for a Hierarchy.134 Will return the element with index 1, if default member is not specified explicitly in }HierarchyProperty Cube135 :param dimension_name:136 :param hierarchy_name:137 :return: String, name of Member138 """139 url = format_url(140 "/api/v1/Dimensions('{dimension}')/Hierarchies('{hierarchy}')/DefaultMember",141 dimension=dimension_name,142 hierarchy=hierarchy_name if hierarchy_name else dimension_name)143 response = self._rest.GET(url=url, **kwargs)144 if not response.text:145 return None146 return response.json()["Name"]147 def update_default_member(self, dimension_name: str, hierarchy_name: str = None, member_name: str = "",148 **kwargs) -> Response:149 """ Update the default member of a hierarchy.150 Currently implemented through TI, since TM1 API does not supports default member updates yet.151 :param dimension_name:152 :param hierarchy_name:153 :param member_name:154 :return:155 """156 from TM1py import ProcessService, CellService157 if hierarchy_name and not case_and_space_insensitive_equals(dimension_name, hierarchy_name):158 dimension = "{}:{}".format(dimension_name, hierarchy_name)159 else:160 dimension = dimension_name161 cells = {(dimension, 'hierarchy0', 'defaultMember'): member_name}162 CellService(self._rest).write_values(163 cube_name="}HierarchyProperties",164 cellset_as_dict=cells,165 dimensions=('}Dimensions', '}Hierarchies', '}HierarchyProperties'),166 **kwargs)167 return ProcessService(self._rest).execute_ti_code(168 lines_prolog=format_url("RefreshMdxHierarchy('{}');", dimension_name),169 **kwargs)170 def remove_all_edges(self, dimension_name: str, hierarchy_name: str = None, **kwargs) -> Response:171 if not hierarchy_name:172 hierarchy_name = dimension_name173 url = format_url("/api/v1/Dimensions('{}')/Hierarchies('{}')", dimension_name, hierarchy_name)174 body = {175 "Edges": []176 }177 return self._rest.PATCH(url=url, data=json.dumps(body), **kwargs)178 def remove_edges_under_consolidation(self, dimension_name: str, hierarchy_name: str,179 consolidation_element: str, **kwargs) -> List[Response]:180 """181 :param dimension_name: Name of the dimension182 :param hierarchy_name: Name of the hierarchy183 :param consolidation_element: Name of the Consolidated element184 :return: response185 """186 hierarchy = self.get(dimension_name, hierarchy_name)187 from TM1py.Services import ElementService188 element_service = ElementService(self._rest)189 elements_under_consolidations = element_service.get_members_under_consolidation(dimension_name, hierarchy_name,190 consolidation_element)191 elements_under_consolidations.append(consolidation_element)192 remove_edges = []193 for (parent, component) in hierarchy.edges:194 if parent in elements_under_consolidations and component in elements_under_consolidations:195 remove_edges.append((parent, component))196 hierarchy.remove_edges(remove_edges)197 return self.update(hierarchy, **kwargs)198 def add_edges(self, dimension_name: str, hierarchy_name: str = None, edges: Dict[Tuple[str, str], int] = None,199 **kwargs) -> Response:200 """ Add Edges to hierarchy. Fails if one edge already exists.201 :param dimension_name:202 :param hierarchy_name:203 :param edges:204 :return:205 """206 return self.elements.add_edges(dimension_name, hierarchy_name, edges, **kwargs)207 def add_elements(self, dimension_name: str, hierarchy_name: str, elements: List[Element], **kwargs):208 """ Add elements to hierarchy. Fails if one element already exists.209 :param dimension_name:210 :param hierarchy_name:211 :param elements:212 :return:213 """214 return self.elements.add_elements(dimension_name, hierarchy_name, elements, **kwargs)215 def add_element_attributes(self, dimension_name: str, hierarchy_name: str,216 element_attributes: List[ElementAttribute], **kwargs):217 """ Add element attributes to hierarchy. Fails if one element attribute already exists.218 :param dimension_name:219 :param hierarchy_name:220 :param element_attributes:221 :return:222 """223 return self.elements.add_element_attributes(dimension_name, hierarchy_name, element_attributes, **kwargs)224 def is_balanced(self, dimension_name: str, hierarchy_name: str, **kwargs):225 """ Check if hierarchy is balanced226 :param dimension_name:227 :param hierarchy_name:228 :return:229 """230 url = format_url(231 "/api/v1/Dimensions('{}')/Hierarchies('{}')/Structure/$value",232 dimension_name,233 hierarchy_name)234 structure = int(self._rest.GET(url, **kwargs).text)235 # 0 = balanced, 2 = unbalanced236 if structure == 0:237 return True238 elif structure == 2:239 return False240 else:...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run Lemoncheesecake automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful