Exemple #1
0
    def __init__(self, tm1_rest):
        """

        :param tm1_rest: instance of RestService
        """
        self._tm1_rest = tm1_rest
        self.cells = CellService(tm1_rest)
        self.elements = ElementService(tm1_rest)
Exemple #2
0
    def __init__(self, **kwargs):
        self._tm1_rest = RestService(**kwargs)

        # instantiate all Services
        self.annotations = AnnotationService(self._tm1_rest)
        self.cells = CellService(self._tm1_rest)
        self.chores = ChoreService(self._tm1_rest)
        self.cubes = CubeService(self._tm1_rest)
        self.dimensions = DimensionService(self._tm1_rest)
        self.elements = ElementService(self._tm1_rest)
        self.hierarchies = HierarchyService(self._tm1_rest)
        self.monitoring = MonitoringService(self._tm1_rest)
        self.power_bi = PowerBiService(self._tm1_rest)
        self.processes = ProcessService(self._tm1_rest)
        self.security = SecurityService(self._tm1_rest)
        self.server = ServerService(self._tm1_rest)
        self.subsets = SubsetService(self._tm1_rest)
        self.applications = ApplicationService(self._tm1_rest)
        self.views = ViewService(self._tm1_rest)
Exemple #3
0
 def _instantiate_services(self):
     self.annotations = AnnotationService(self._tm1_rest)
     self.cells = CellService(self._tm1_rest)
     self.chores = ChoreService(self._tm1_rest)
     self.cubes = CubeService(self._tm1_rest)
     self.dimensions = DimensionService(self._tm1_rest)
     self.elements = ElementService(self._tm1_rest)
     self.git = GitService(self._tm1_rest)
     self.hierarchies = HierarchyService(self._tm1_rest)
     self.monitoring = MonitoringService(self._tm1_rest)
     self.power_bi = PowerBiService(self._tm1_rest)
     self.processes = ProcessService(self._tm1_rest)
     self.security = SecurityService(self._tm1_rest)
     self.server = ServerService(self._tm1_rest)
     self.subsets = SubsetService(self._tm1_rest)
     self.applications = ApplicationService(self._tm1_rest)
     self.views = ViewService(self._tm1_rest)
     self.sandboxes = SandboxService(self._tm1_rest)
     self.git = GitService(self._tm1_rest)
Exemple #4
0
class PowerBiService:
    def __init__(self, tm1_rest):
        """

        :param tm1_rest: instance of RestService
        """
        self._tm1_rest = tm1_rest
        self.cells = CellService(tm1_rest)
        self.elements = ElementService(tm1_rest)

    @require_pandas
    def execute_mdx(self, mdx, **kwargs) -> 'pd.DataFrame':
        return self.cells.execute_mdx_dataframe_shaped(mdx, **kwargs)

    @require_pandas
    def execute_view(self, cube_name, view_name, private,
                     **kwargs) -> 'pd.DataFrame':
        return self.cells.execute_view_dataframe_shaped(
            cube_name, view_name, private, **kwargs)

    @require_pandas
    def get_member_properties(self,
                              dimension_name: str,
                              hierarchy_name: str,
                              member_selection: Iterable = None,
                              skip_consolidations: bool = True,
                              attributes: Iterable = None,
                              skip_parents: bool = False,
                              level_names=None,
                              parent_attribute: str = None) -> 'pd.DataFrame':
        """

        :param dimension_name: Name of the dimension
        :param hierarchy_name: Name of the hierarchy in the dimension
        :param member_selection: Selection of members. Iterable or valid MDX string
        :param skip_consolidations: Boolean flag to skip consolidations
        :param attributes: Selection of attributes. Iterable. If None retrieve all.
        :param level_names: List of labels for parent columns. If None use level names from TM1.
        :param skip_parents: Boolean Flag to skip parent columns.
        :param parent_attribute: Attribute to be displayed in parent columns. If None, parent name is used.
        :return: pandas DataFrame
        """
        if not member_selection:
            member_selection = f"{{ [{dimension_name}].[{hierarchy_name}].Members }}"
            if skip_consolidations:
                member_selection = f"{{ Tm1FilterByLevel({member_selection}, 0) }}"

        if not isinstance(member_selection, str):
            if isinstance(member_selection, Iterable):
                member_selection = "{" + ",".join(
                    f"[{dimension_name}].[{member}]"
                    for member in member_selection) + "}"
            else:
                raise ValueError(
                    "Argument 'element_selection' must be None or str")

        if not self.elements.attribute_cube_exists(dimension_name):
            raise RuntimeError(self.elements.ELEMENT_ATTRIBUTES_PREFIX +
                               dimension_name + " cube must exist")

        members = [
            tupl[0]
            for tupl in self.elements.execute_set_mdx(mdx=member_selection,
                                                      element_properties=None,
                                                      member_properties=(
                                                          "Name",
                                                          "UniqueName"),
                                                      parent_properties=None)
        ]

        element_types = self.elements.get_element_types(
            dimension_name=dimension_name,
            hierarchy_name=hierarchy_name,
            skip_consolidations=skip_consolidations)

        df = pd.DataFrame(data=[(member["Name"], element_types[member["Name"]])
                                for member in members
                                if member["Name"] in element_types],
                          dtype=str,
                          columns=[dimension_name, 'Type'])

        calculated_members_definition = list()
        calculated_members_selection = list()
        if not skip_parents:
            levels = self.elements.get_levels_count(dimension_name,
                                                    hierarchy_name)

            # potential custom parent names
            if not level_names:
                level_names = self.elements.get_level_names(dimension_name,
                                                            hierarchy_name,
                                                            descending=True)

            for parent in range(1, levels, 1):
                name_or_attribute = f"Properties('{parent_attribute}')" if parent_attribute else "Name"
                member = f"""
                    MEMBER [{self.elements.ELEMENT_ATTRIBUTES_PREFIX + dimension_name}].[{level_names[parent]}] 
                    AS [{dimension_name}].CurrentMember.{'Parent.' * parent}{name_or_attribute}
                    """
                calculated_members_definition.append(member)

                calculated_members_selection.append(
                    f"[{self.elements.ELEMENT_ATTRIBUTES_PREFIX + dimension_name}].[{level_names[parent]}]"
                )

        if attributes is None:
            column_selection = "{Tm1SubsetAll([" + self.elements.ELEMENT_ATTRIBUTES_PREFIX + dimension_name + "])}"
        else:
            column_selection = "{" + ",".join(
                "[" + self.elements.ELEMENT_ATTRIBUTES_PREFIX +
                dimension_name + "].[" + attribute + "]"
                for attribute in attributes) + "}"

        if calculated_members_selection:
            column_selection = column_selection + " + {" + ",".join(
                calculated_members_selection) + "}"
        member_selection = ",".join(member["UniqueName"] for member in members)

        mdx_with_block = ""
        if calculated_members_definition:
            mdx_with_block = "WITH " + " ".join(calculated_members_definition)

        mdx = f"""
        {mdx_with_block}
        SELECT
        {{ {member_selection} }} ON ROWS,
        {{ {column_selection} }} ON COLUMNS
        FROM [{self.elements.ELEMENT_ATTRIBUTES_PREFIX + dimension_name}]  
        """

        df_data = self.execute_mdx(mdx)

        # shift levels to right hand side
        if not skip_parents:
            # skip max level (= leaves)
            level_names = level_names[1:]
            # iterative approach
            for _ in level_names:
                rows_to_shift = df_data[df_data[level_names[-1]] == ''].index
                if rows_to_shift.empty:
                    break
                df_data.iloc[rows_to_shift, -len(level_names):] = df_data.iloc[
                    rows_to_shift, -len(level_names):].shift(1, axis=1)

            df_data.iloc[:,
                         -len(level_names):] = df_data.iloc[:,
                                                            -len(level_names
                                                                 ):].fillna('')

        return pd.merge(df, df_data, on=dimension_name).drop_duplicates()
Exemple #5
0
class PowerBiService:
    def __init__(self, tm1_rest):
        """

        :param tm1_rest: instance of RestService
        """
        self._tm1_rest = tm1_rest
        self.cells = CellService(tm1_rest)
        self.elements = ElementService(tm1_rest)

    def execute_mdx(self, mdx, **kwargs):
        cellset_id = self.cells.create_cellset(mdx)
        return self.cells.extract_cellset_power_bi(cellset_id, **kwargs)

    def execute_view(self, cube_name, view_name, private, **kwargs):
        cellset_id = self.cells.create_cellset_from_view(
            cube_name, view_name, private)
        return self.cells.extract_cellset_power_bi(cellset_id, **kwargs)

    def get_member_properties(self,
                              dimension_name,
                              hierarchy_name,
                              member_selection=None,
                              skip_consolidations=True,
                              attributes=None,
                              skip_parents=False,
                              level_names=None):
        """

        :param dimension_name: Name of the dimension
        :param hierarchy_name: Name of the hierarchy in the dimension
        :param member_selection: Selection of members. Iterable or valid MDX string
        :param skip_consolidations: Boolean flag to skip consolidations
        :param attributes: Selection of attributes. Iterable. If None retrieve all.
        :param level_names: List of labels for parent columns. If None use level names from TM1.
        :param skip_parents: Boolean Flag to skip parent columns.
        :return: pandas DataFrame
        """
        if not member_selection:
            member_selection = f"{{ [{dimension_name}].[{hierarchy_name}].Members }}"
            if skip_consolidations:
                member_selection = f"{{ Tm1FilterByLevel({member_selection}, 0) }}"

        if not isinstance(member_selection, str):
            if isinstance(member_selection, Iterable):
                member_selection = "{" + ",".join(
                    f"[{dimension_name}].[{member}]"
                    for member in member_selection) + "}"
            else:
                raise ValueError(
                    "Argument 'element_selection' must be None or str")

        if not self.elements.attribute_cube_exists(dimension_name):
            raise RuntimeError(self.elements.ELEMENT_ATTRIBUTES_PREFIX +
                               dimension_name + " cube must exist")

        members = [
            tupl[0]
            for tupl in self.elements.execute_set_mdx(mdx=member_selection,
                                                      element_properties=None,
                                                      member_properties=(
                                                          "Name",
                                                          "UniqueName"),
                                                      parent_properties=None)
        ]

        element_types = self.elements.get_element_types(
            dimension_name=dimension_name,
            hierarchy_name=hierarchy_name,
            skip_consolidations=skip_consolidations)

        df = pd.DataFrame(data=[(member["Name"], element_types[member["Name"]])
                                for member in members
                                if member["Name"] in element_types],
                          dtype=str,
                          columns=[dimension_name, 'Type'])

        calculated_members_definition = list()
        calculated_members_selection = list()
        if not skip_parents:
            levels = self.elements.get_levels_count(dimension_name,
                                                    hierarchy_name)

            # potential custom parent names
            if not level_names:
                level_names = self.elements.get_level_names(
                    dimension_name, hierarchy_name)

            for parent in range(1, levels, 1):
                calculated_members_definition.append(f"""
                    MEMBER [{self.elements.ELEMENT_ATTRIBUTES_PREFIX + dimension_name}].[{level_names[parent]}] 
                    AS [{dimension_name}].CurrentMember.{'Parent.' * parent}Name
                    """)

                calculated_members_selection.append(
                    f"[{self.elements.ELEMENT_ATTRIBUTES_PREFIX + dimension_name}].[{level_names[parent]}]"
                )

        if attributes is None:
            column_selection = "{Tm1SubsetAll([" + self.elements.ELEMENT_ATTRIBUTES_PREFIX + dimension_name + "])}"
        else:
            column_selection = "{" + ",".join(
                "[" + self.elements.ELEMENT_ATTRIBUTES_PREFIX +
                dimension_name + "].[" + attribute + "]"
                for attribute in attributes) + "}"

        if calculated_members_selection:
            column_selection = column_selection + " + {" + ",".join(
                calculated_members_selection) + "}"
        member_selection = ",".join(member["UniqueName"] for member in members)

        mdx_with_block = ""
        if calculated_members_definition:
            mdx_with_block = "WITH " + " ".join(calculated_members_definition)

        mdx = f"""
        {mdx_with_block}
        SELECT
        {{ {member_selection} }} ON ROWS,
        {{ {column_selection} }} ON COLUMNS
        FROM [{self.elements.ELEMENT_ATTRIBUTES_PREFIX + dimension_name}]  
        """

        df_data = self.execute_mdx(mdx, element_unique_names=False)

        return pd.merge(df, df_data, on=dimension_name)