Esempio n. 1
0
def get_tm1_service(settings):
    address = settings['ServerAddress']
    port = settings['PortNumber']
    user = settings['UserName']
    ssl = True if settings['UseSSL'] == 'T' else False
    password = decode("1234567890", settings['Password'])
    namespace = settings['CAMNamespaceID']

    session_name = '{}_{}_{}_{}'.format(address, port, user, namespace)

    cookie_path = tempfile.gettempdir()
    cookie_file = os.path.join(cookie_path, urlsafe_b64encode(session_name.encode()).decode() + ".tm1_session")

    namespace = None if len(namespace) == 0 else namespace

    connected = False
    if os.path.isfile(cookie_file):
        try:
            service = TM1Service.restore_from_file(cookie_file)
            if service._tm1_rest.is_connected():
                connected = True
        except TM1pyException as e:
            pass

    if not connected:
        try:
            service = TM1Service(address=address, port=port, user=user, password=password, namespace=namespace, ssl=ssl)
            connected = True
        except TM1pyException as e:
            raise

    service.save_to_file(cookie_file)

    return service
Esempio n. 2
0
def setup_tm1_services(max_workers: int, tasks_file_path: str,
                       execution_mode: ExecutionMode) -> dict:
    """ Return Dictionary with TM1ServerName (as in config.ini) : Instantiated TM1Service
    
    :return: Dictionary server_names and TM1py.TM1Service instances pairs
    """
    if not os.path.isfile(CONFIG):
        raise ValueError("{config} does not exist".format(config=CONFIG))

    tm1_instances_in_tasks = get_instances_from_tasks_file(
        execution_mode, max_workers, tasks_file_path)

    tm1_services = dict()
    # parse .ini
    config = configparser.ConfigParser()
    config.read(CONFIG, encoding='utf-8')
    # build tm1_services dictionary
    for tm1_server_name, params in config.items():
        if tm1_server_name not in tm1_instances_in_tasks:
            continue

        # handle default values from configparser
        if tm1_server_name != config.default_section:
            try:
                tm1_services[tm1_server_name] = TM1Service(
                    **params,
                    session_context=APP_NAME,
                    connection_pool_size=max_workers)
            # Instance not running, Firewall or wrong connection parameters
            except Exception as e:
                logger.error(
                    "TM1 instance {} not accessible. Error: {}".format(
                        tm1_server_name, str(e)))
    return tm1_services
Esempio n. 3
0
def setup_tm1_services(maximum_workers):
    """ Return Dictionary with TM1ServerName (as in config.ini) : Instantiated TM1Service
    
    :return: Dictionary server_names and TM1py.TM1Service instances pairs
    """
    if not os.path.isfile(CONFIG):
        raise ValueError("{config} does not exist.".format(config=CONFIG))
    tm1_services = dict()
    # parse .ini
    config = configparser.ConfigParser()
    config.read(CONFIG)
    # build tm1_services dictionary
    for tm1_server_name, params in config.items():
        # handle default values from configparser
        if tm1_server_name != config.default_section:
            try:
                tm1_services[tm1_server_name] = TM1Service(
                    **params,
                    session_context=APP_NAME,
                    connection_pool_size=maximum_workers
                )
            # Instance not running, Firewall or wrong connection parameters
            except Exception as e:
                logging.error(
                    "TM1 instance {} not accessible. Error: {}".format(
                        tm1_server_name, str(e)
                    )
                )
    return tm1_services
Esempio n. 4
0
 def job():
     entries = tm1_source.server.execute_transaction_log_delta_request()
     if len(entries) > 0:
         cellset = dict()
         for entry in entries:
             cellset[tuple(entry["Tuple"])] = entry["NewValue"]
         with TM1Service(**config['tm1srv02']) as tm1_target:
             tm1_target.cubes.cells.write_values(cube_target, cellset)
Esempio n. 5
0
    def setUpClass(cls):
        """
        Establishes a connection to TM1 and creates TM! objects to use across all tests
        """

        # Connection to TM1
        cls.config = configparser.ConfigParser()
        cls.config.read(Path(__file__).parent.joinpath('config.ini'))
        cls.tm1 = TM1Service(**cls.config['tm1srv01'])
def collect_mdx_of_views_and_subsets():
    lines = []
    with TM1Service(address=ADDRESS,
                    port=PORT,
                    user=USER,
                    password=PWD,
                    namespace='',
                    gateway='',
                    ssl=SSL) as tm1:
        parse_views(tm1, lines)
        parse_subsets(tm1, lines)

    # specify the dimension and hierarchy
    with open(OUTPUT_FILE, "w") as file:
        file.writelines(lines)
Esempio n. 7
0
    def setUpClass(cls) -> None:
        """
        Establishes a connection to TM1 and creates TM1 objects to use across all tests
        """

        # Connection to TM1
        cls.config = configparser.ConfigParser()
        cls.config.read(Path(__file__).parent.joinpath('config.ini'))
        cls.tm1 = TM1Service(**cls.config['tm1srv01'])

        # Build Dimensions
        for dimension_name in DIMENSION_NAMES:
            elements = [Element('Element {}'.format(str(j)), 'Numeric') for j in range(1, 1001)]
            element_attributes = [ElementAttribute("Attr1", "String"),
                                  ElementAttribute("Attr2", "Numeric"),
                                  ElementAttribute("Attr3", "Numeric")]
            hierarchy = Hierarchy(dimension_name=dimension_name,
                                  name=dimension_name,
                                  elements=elements,
                                  element_attributes=element_attributes)
            dimension = Dimension(dimension_name, [hierarchy])
            if cls.tm1.dimensions.exists(dimension.name):
                cls.tm1.dimensions.update(dimension)
            else:
                cls.tm1.dimensions.create(dimension)

        # Build Cube
        cube = Cube(CUBE_NAME, DIMENSION_NAMES)
        if not cls.tm1.cubes.exists(CUBE_NAME):
            cls.tm1.cubes.create(cube)

        # Build cube view
        view = NativeView(
            cube_name=CUBE_NAME,
            view_name=VIEW_NAME,
            suppress_empty_columns=True,
            suppress_empty_rows=True)
        view.add_row(
            dimension_name=DIMENSION_NAMES[0],
            subset=AnonymousSubset(
                dimension_name=DIMENSION_NAMES[0],
                expression='{[' + DIMENSION_NAMES[0] + '].Members}'))
        view.add_row(
            dimension_name=DIMENSION_NAMES[1],
            subset=AnonymousSubset(
                dimension_name=DIMENSION_NAMES[1],
                expression='{[' + DIMENSION_NAMES[1] + '].Members}'))
        view.add_column(
            dimension_name=DIMENSION_NAMES[2],
            subset=AnonymousSubset(
                dimension_name=DIMENSION_NAMES[2],
                expression='{[' + DIMENSION_NAMES[2] + '].Members}'))
        if not cls.tm1.cubes.views.exists(CUBE_NAME, view.name, private=False):
            cls.tm1.cubes.views.create(
                view=view,
                private=False)

        # Build subset
        subset = Subset(SUBSET_NAME, DIMENSION_NAMES[0], DIMENSION_NAMES[0], None, None, ["Element 1"])
        if cls.tm1.dimensions.hierarchies.subsets.exists(
                subset.name,
                subset.dimension_name,
                subset.hierarchy_name,
                False):
            cls.tm1.dimensions.hierarchies.subsets.delete(
                subset.name,
                subset.dimension_name,
                subset.hierarchy_name,
                False)
        cls.tm1.dimensions.hierarchies.subsets.create(subset, False)

        # Build process
        p1 = Process(name=PROCESS_NAME)
        p1.add_parameter('pRegion', 'pRegion (String)', value='US')
        if cls.tm1.processes.exists(p1.name):
            cls.tm1.processes.delete(p1.name)
        cls.tm1.processes.create(p1)

        # Build chore
        c1 = Chore(
            name=CHORE_NAME,
            start_time=ChoreStartTime(datetime.now().year, datetime.now().month, datetime.now().day,
                                      datetime.now().hour, datetime.now().minute, datetime.now().second),
            dst_sensitivity=False,
            active=True,
            execution_mode=Chore.MULTIPLE_COMMIT,
            frequency=ChoreFrequency(
                days=int(random.uniform(0, 355)),
                hours=int(random.uniform(0, 23)),
                minutes=int(random.uniform(0, 59)),
                seconds=int(random.uniform(0, 59))),
            tasks=[ChoreTask(0, PROCESS_NAME, parameters=[{'Name': 'pRegion', 'Value': 'UK'}])])
        cls.tm1.chores.create(c1)

        # create Folder
        app = FolderApplication("", TM1PY_APP_FOLDER)
        cls.tm1.applications.create(application=app, private=False)
import configparser
from getpass import getpass

import keyring
from TM1py import TM1Service

INSTANCE = "tm1srv01"

config = configparser.ConfigParser()
config.read(r'..\config.ini')

address = config[INSTANCE]["address"]
port = config[INSTANCE]["port"]
ssl = config[INSTANCE]["ssl"]
user = config[INSTANCE]["user"]

# interact with Windows Credential Manager through the keyring library
password = keyring.get_password(INSTANCE, user)
if not password:
    password = getpass(
        f"Please insert password for user '{user}' and instance '{INSTANCE}':")
keyring.set_password(INSTANCE, user, password)

with TM1Service(**config[INSTANCE]) as tm1:
    tm1_version = tm1.server.get_product_version()
    print(tm1_version)
Esempio n. 9
0
def main(instance_name: str, cube_name: str, view_names: List[str],
         measure_dimension_only_numeric: bool, max_permutations: int,
         executions: int, mode: ExecutionMode):
    from executors import OriginalOrderExecutor, OneShotExecutor, GreedyExecutor, BruteForceExecutor, BestExecutor

    with TM1Service(**config[instance_name], session_context=APP_NAME) as tm1:
        original_dimension_order = tm1.cubes.get_storage_dimension_order(
            cube_name=cube_name)
        displayed_dimension_order = tm1.cubes.get_dimension_names(
            cube_name=cube_name)

        try:
            permutation_results = list()

            original_order = OriginalOrderExecutor(
                tm1, cube_name, view_names, displayed_dimension_order,
                executions, measure_dimension_only_numeric,
                original_dimension_order)
            permutation_results += original_order.execute()

            # One Shot goes first, as it may blow up the overall RAM for the cube
            if mode == ExecutionMode.ALL or mode == ExecutionMode.ONE_SHOT:
                one_shot = OneShotExecutor(tm1, cube_name, view_names,
                                           displayed_dimension_order,
                                           executions,
                                           measure_dimension_only_numeric)
                permutation_results += one_shot.execute()

            if mode == ExecutionMode.ALL or mode == ExecutionMode.BRUTE_FORCE:
                brute_force = BruteForceExecutor(
                    tm1, cube_name, view_names, displayed_dimension_order,
                    executions, measure_dimension_only_numeric,
                    max_permutations)
                permutation_results += brute_force.execute()

            if mode == ExecutionMode.ALL or mode == ExecutionMode.GREEDY:
                greedy = GreedyExecutor(tm1, cube_name, view_names,
                                        displayed_dimension_order, executions,
                                        measure_dimension_only_numeric,
                                        max_permutations)
                permutation_results += greedy.execute()

            if mode == ExecutionMode.ALL or mode == ExecutionMode.BEST:
                best = BestExecutor(tm1, cube_name, view_names,
                                    displayed_dimension_order, executions,
                                    measure_dimension_only_numeric)
                permutation_results += best.execute()

            optimus_result = OptimusResult(cube_name, permutation_results)

            logging.info("Analysis Completed")
            logging.info("More details in csv and png files in results folder")
            for view_name in view_names:
                optimus_result.to_csv(
                    view_name,
                    RESULT_CSV.format(cube_name, view_name, TIME_STAMP))
                optimus_result.to_png(
                    view_name,
                    RESULT_PNG.format(cube_name, view_name, TIME_STAMP))
            return True

        except:
            logging.error("Fatal error", exc_info=True)
            return False

        finally:
            logging.info("Reestablishing original dimension order")
            tm1.cubes.update_storage_dimension_order(cube_name,
                                                     original_dimension_order)
Esempio n. 10
0
 def setUpClass(cls):
     cls.tm1 = TM1Service(**config['tm1srv01'])
Esempio n. 11
0
from TM1py import TM1Service, NativeView, AnonymousSubset

mdx = """
SELECT
NON EMPTY {[Date].[2017-11-26], [Date].[2017-11-27]} * {[Bike Shares Measure].[Count]} ON ROWS,
NON EMPTY {[City].[NYC], [City].[Chicago]} ON COLUMNS
FROM [Bike Shares]
WHERE ([Version].[Actual])
"""

with TM1Service(address='10.77.19.60', port=12354, user='******', password='******', ssl=True) as tm1:
    pivot = tm1.cubes.cells.execute_mdx_dataframe_pivot(mdx=mdx)
    print(pivot)

view = NativeView(
    cube_name="Bike Shares",
    view_name="Bike Shares By City",
    suppress_empty_columns=True,
    suppress_empty_rows=True)
view.add_row(
    dimension_name="Date",
    subset=AnonymousSubset(
        dimension_name="Date",
        expression="{Tm1SubsetAll([Date])}"))
view.add_row(
    dimension_name="Bike Shares Measure",
    subset=AnonymousSubset(
        dimension_name="Bike Shares Measure",
        elements=["Count"]))
view.add_column(
    dimension_name="City",
Esempio n. 12
0
import tkinter
from GUI import Application
from TM1py import TM1Service

app = Application()
app.master.title=('Sample Application')
app.mainloop()

with TM1Service(address=app.TM1AddressEntry.get(), port=app.TM1PortEntry.get(), user=app.TM1UsernameEntry.get()
            , password=app.TM1PasswordEntry.get(), ssl=app.sslvar.get()) as tm1:

    cubelist=tm1.cubes.get_all_names()
    for cube in cubelist:
        print ("Cube name: ", cube)

### Simple cube list print. Parameters being used are:
### address = localhost, port = 8002, user = admin, password = '', ssl = True

Esempio n. 13
0
import configparser
config = configparser.ConfigParser()
config.read('..\config.ini')

import time

from TM1py import TM1Service

cube_source = "Retail"
cube_target = "Retail"

# Establish connection to TM1 Source
with TM1Service(**config['tm1srv01']) as tm1_source:

    # Start Change Tracking
    tm1_source.server.initialize_transaction_log_delta_requests("Cube eq '" +
                                                                cube_source +
                                                                "'")

    # Continuous checks
    def job():
        entries = tm1_source.server.execute_transaction_log_delta_request()
        if len(entries) > 0:
            cellset = dict()
            for entry in entries:
                cellset[tuple(entry["Tuple"])] = entry["NewValue"]
            with TM1Service(**config['tm1srv02']) as tm1_target:
                tm1_target.cubes.cells.write_values(cube_target, cellset)

    while True:
        job()
Esempio n. 14
0
def main(instance_name: str,
         view_name: str,
         process_name: str,
         executions: int,
         fast: bool,
         output: str,
         update: bool,
         password: str = None):
    config = get_tm1_config()
    tm1_args = dict(config[instance_name])
    tm1_args['session_context'] = APP_NAME
    if password:
        tm1_args['password'] = password
        tm1_args['decode_b64'] = False

    with TM1Service(**tm1_args) as tm1:
        original_performance_monitor_state = retrieve_performance_monitor_state(
            tm1)
        activate_performance_monitor(tm1)

        model_cubes = filter(lambda c: not c.startswith("}"),
                             tm1.cubes.get_all_names())
        for cube_name in model_cubes:
            if not tm1.cubes.views.exists(cube_name, view_name, private=False):
                logging.info(
                    f"Skipping cube '{cube_name}' since view '{view_name}' does not exist"
                )
                continue

            original_vmm, original_vmt = retrieve_vmm_vmt(tm1, cube_name)
            write_vmm_vmt(tm1, cube_name, "1000000", "1000000")

            logging.info(f"Starting analysis for cube '{cube_name}'")
            original_dimension_order = tm1.cubes.get_storage_dimension_order(
                cube_name=cube_name)
            logging.info(
                f"Original dimension order for cube '{cube_name}' is: '{original_dimension_order}'"
            )
            displayed_dimension_order = tm1.cubes.get_dimension_names(
                cube_name=cube_name)
            measure_dimension_only_numeric = is_dimension_only_numeric(
                tm1, original_dimension_order[-1])

            permutation_results = list()
            try:

                original_order = OriginalOrderExecutor(
                    tm1, cube_name, [view_name], process_name,
                    displayed_dimension_order, executions,
                    measure_dimension_only_numeric, original_dimension_order)
                permutation_results += original_order.execute(
                    reset_counter=True)

                main_executor = MainExecutor(tm1, cube_name, [view_name],
                                             process_name,
                                             displayed_dimension_order,
                                             executions,
                                             measure_dimension_only_numeric,
                                             fast)
                permutation_results += main_executor.execute()

                optimus_result = OptimusResult(cube_name, permutation_results)

                best_permutation = optimus_result.best_result
                logging.info(f"Completed analysis for cube '{cube_name}'")
                if not best_permutation:
                    logging.info(
                        f"No ideal dimension order found for cube '{cube_name}'."
                        f"Please pick manually based on csv and png results.")

                else:
                    best_order = best_permutation.dimension_order
                    if update:
                        tm1.cubes.update_storage_dimension_order(
                            cube_name, best_order)
                        logging.info(
                            f"Updated dimension order for cube '{cube_name}' to {best_order}"
                        )
                    else:
                        logging.info(
                            f"Best order for cube '{cube_name}': {best_order}")
                        tm1.cubes.update_storage_dimension_order(
                            cube_name, original_dimension_order)
                        logging.info(
                            f"Restored original dimension order for cube '{cube_name}' to {original_dimension_order}"
                        )

            except:
                logging.error("Fatal error", exc_info=True)
                return False

            finally:
                with suppress(Exception):
                    write_vmm_vmt(tm1, cube_name, original_vmm, original_vmt)

                with suppress(Exception):
                    if original_performance_monitor_state:
                        activate_performance_monitor(tm1)
                    else:
                        deactivate_performance_monitor(tm1)

                if len(permutation_results) > 0:
                    optimus_result = OptimusResult(cube_name,
                                                   permutation_results)
                    optimus_result.to_png(
                        view_name, process_name,
                        RESULT_PATH / RESULT_PNG.format(
                            cube_name, view_name, process_name, TIME_STAMP))

                    if output.upper() == "XLSX":
                        optimus_result.to_xlsx(
                            view_name, process_name, RESULT_PATH /
                            RESULT_XLSX.format(cube_name, view_name,
                                               process_name, TIME_STAMP))

                    else:
                        if not output.upper() == "CSV":
                            logging.warning(
                                "Value for -o / --output must be 'CSV' or 'XLSX'. Default is CSV"
                            )
                        optimus_result.to_csv(
                            view_name, process_name, RESULT_PATH /
                            RESULT_CSV.format(cube_name, view_name,
                                              process_name, TIME_STAMP))

    return True
Esempio n. 15
0
 def setup_class(cls):
     # Connection to TM1
     cls.tm1 = TM1Service(**config['tm1srv01'])
Esempio n. 16
0
class TestDecorators(unittest.TestCase):
    tm1 = TM1Service(**config["tm1srv01"])

    @classmethod
    def setUpClass(cls):
        cls.dimension1 = Dimension(
            name=DIMENSION_NAMES[0],
            hierarchies=[
                Hierarchy(name=DIMENSION_NAMES[0],
                          dimension_name=DIMENSION_NAMES[0],
                          elements=[
                              Element(name="Element_{}".format(i),
                                      element_type="Numeric")
                              for i in range(1, 101)
                          ])
            ])
        cls.dimension2 = Dimension(
            name=DIMENSION_NAMES[1],
            hierarchies=[
                Hierarchy(name=DIMENSION_NAMES[1],
                          dimension_name=DIMENSION_NAMES[1],
                          elements=[
                              Element(name="Element_{}".format(i),
                                      element_type="Numeric")
                              for i in range(1, 101)
                          ])
            ])
        cls.cube_source = Cube(name=CUBE_NAME_SOURCE,
                               dimensions=DIMENSION_NAMES)
        cls.cube_target = Cube(name=CUBE_NAME_TARGET,
                               dimensions=DIMENSION_NAMES)

    @classmethod
    def tearDownClass(cls):
        cls.tm1.logout()

    def setUp(self):
        if not self.tm1.dimensions.exists(dimension_name=self.dimension1.name):
            self.tm1.dimensions.create(dimension=self.dimension1)
        if not self.tm1.dimensions.exists(dimension_name=self.dimension2.name):
            self.tm1.dimensions.create(dimension=self.dimension2)
        if not self.tm1.cubes.exists(cube_name=self.cube_source.name):
            self.tm1.cubes.create(cube=self.cube_source)
        if not self.tm1.cubes.exists(cube_name=self.cube_target.name):
            self.tm1.cubes.create(cube=self.cube_target)

    def tearDown(self):
        self.tm1.cubes.delete(cube_name=self.cube_source.name)
        self.tm1.cubes.delete(cube_name=self.cube_target.name)
        self.tm1.dimensions.delete(dimension_name=self.dimension1.name)
        self.tm1.dimensions.delete(dimension_name=self.dimension2.name)

    def test_tm1io_input_nativeview_output_nativeview(self):
        # create input view
        view_input = NativeView(cube_name=CUBE_NAME_SOURCE,
                                view_name=VIEW_NAME_SOURCE,
                                suppress_empty_columns=False,
                                suppress_empty_rows=False)
        view_input.add_row(
            dimension_name=DIMENSION_NAMES[0],
            subset=AnonymousSubset(dimension_name=DIMENSION_NAMES[0],
                                   expression="{ HEAD ( { [" +
                                   DIMENSION_NAMES[0] + "].Members}," +
                                   str(len(IRR_INPUT_VALUES)) + ") }"))
        view_input.add_column(
            dimension_name=DIMENSION_NAMES[1],
            subset=AnonymousSubset(dimension_name=DIMENSION_NAMES[1],
                                   expression="{[" + DIMENSION_NAMES[1] +
                                   "].[Element_1]}"))
        self.tm1.cubes.views.create(view=view_input, private=False)
        # create output view
        view_output = NativeView(cube_name=CUBE_NAME_TARGET,
                                 view_name=VIEW_NAME_TARGET,
                                 suppress_empty_columns=False,
                                 suppress_empty_rows=False)
        view_output.add_row(
            dimension_name=DIMENSION_NAMES[0],
            subset=AnonymousSubset(dimension_name=DIMENSION_NAMES[0],
                                   expression="{[" + DIMENSION_NAMES[0] +
                                   "].[Element_1]}"))
        view_output.add_column(
            dimension_name=DIMENSION_NAMES[1],
            subset=AnonymousSubset(dimension_name=DIMENSION_NAMES[1],
                                   expression="{[" + DIMENSION_NAMES[1] +
                                   "].[Element_1]}"))
        self.tm1.cubes.views.create(view=view_output, private=False)
        # write values into input view
        mdx = view_input.MDX
        self.tm1.cubes.cells.write_values_through_cellset(
            mdx, IRR_INPUT_VALUES)
        # execute method
        result = irr(tm1_services={
            "tm1srv01": self.tm1,
            "tm1srv02": self.tm1
        },
                     tm1_source="tm1srv01",
                     tm1_target="tm1srv02",
                     cube_source=CUBE_NAME_SOURCE,
                     cube_target=CUBE_NAME_TARGET,
                     view_source=VIEW_NAME_SOURCE,
                     view_target=VIEW_NAME_TARGET)
        self.assertAlmostEqual(IRR_EXPECTED_RESULT,
                               result,
                               delta=IRR_TOLERANCE)
        # check output view
        cell_value = next(
            self.tm1.cubes.cells.execute_view_values(
                cube_name=CUBE_NAME_TARGET,
                view_name=VIEW_NAME_TARGET,
                private=False))
        self.assertAlmostEqual(cell_value,
                               IRR_EXPECTED_RESULT,
                               delta=IRR_TOLERANCE)

    def test_tm1io_input_mdx_view_output_mdx_view(self):
        # create input view
        mdx_input = MDX_TEMPLATE_SHORT.format(
            rows="{ HEAD ( { [" + DIMENSION_NAMES[0] + "].Members}," +
            str(len(STDEV_INPUT_VALUES)) + ") }",
            columns="{[" + DIMENSION_NAMES[1] + "].[Element_1]}",
            cube=CUBE_NAME_SOURCE)
        view_input = MDXView(cube_name=CUBE_NAME_SOURCE,
                             view_name=VIEW_NAME_SOURCE,
                             MDX=mdx_input)
        self.tm1.cubes.views.create(view=view_input, private=False)
        # create output view
        mdx_output = MDX_TEMPLATE_SHORT.format(
            rows="{[" + DIMENSION_NAMES[0] + "].[Element_1]}",
            columns="{[" + DIMENSION_NAMES[1] + "].[Element_1]}",
            cube=CUBE_NAME_TARGET)
        view_output = MDXView(cube_name=CUBE_NAME_TARGET,
                              view_name=VIEW_NAME_TARGET,
                              MDX=mdx_output)
        self.tm1.cubes.views.create(view=view_output, private=False)
        # write values into input view
        mdx = view_input.MDX
        self.tm1.cubes.cells.write_values_through_cellset(
            mdx, STDEV_INPUT_VALUES)
        # execute method
        result = stdev(tm1_services={
            "tm1srv01": self.tm1,
            "tm1srv02": self.tm1
        },
                       tm1_source="tm1srv01",
                       tm1_target="tm1srv02",
                       cube_source=CUBE_NAME_SOURCE,
                       cube_target=CUBE_NAME_TARGET,
                       view_source=VIEW_NAME_SOURCE,
                       view_target=VIEW_NAME_TARGET)
        self.assertAlmostEqual(STDEV_EXPECTED_RESULT,
                               result,
                               delta=STDEV_TOLERANCE)
        # check output view
        cell_value = next(
            self.tm1.cubes.cells.execute_view_values(
                cube_name=CUBE_NAME_TARGET,
                view_name=VIEW_NAME_TARGET,
                private=False))
        self.assertAlmostEqual(cell_value,
                               STDEV_EXPECTED_RESULT,
                               delta=STDEV_TOLERANCE)

    def test_tm1io_input_view(self):
        # define input view and output view
        mdx_input = MDX_TEMPLATE_SHORT.format(
            rows="{ HEAD ( { [" + DIMENSION_NAMES[0] + "].Members}," +
            str(len(IRR_INPUT_VALUES)) + ") }",
            columns="{[" + DIMENSION_NAMES[1] + "].[Element_1]}",
            cube=CUBE_NAME_SOURCE)
        view_input = MDXView(cube_name=CUBE_NAME_SOURCE,
                             view_name=VIEW_NAME_SOURCE,
                             MDX=mdx_input)
        self.tm1.cubes.views.create(view=view_input, private=False)
        # write values into input view
        mdx = view_input.MDX
        self.tm1.cubes.cells.write_values_through_cellset(
            mdx, IRR_INPUT_VALUES)
        # execute method
        result = irr(tm1_services={
            "tm1srv01": self.tm1,
            "tm1srv02": self.tm1
        },
                     tm1_source="tm1srv01",
                     cube_source=CUBE_NAME_SOURCE,
                     view_source=VIEW_NAME_SOURCE)
        self.assertAlmostEqual(IRR_EXPECTED_RESULT,
                               result,
                               delta=IRR_TOLERANCE)

    def test_tm1io_input_values_output_view(self):
        # define output view
        mdx_output = MDX_TEMPLATE_SHORT.format(
            rows="{[" + DIMENSION_NAMES[0] + "].[Element_1]}",
            columns="{[" + DIMENSION_NAMES[1] + "].[Element_1]}",
            cube=CUBE_NAME_TARGET)
        view_output = MDXView(cube_name=CUBE_NAME_TARGET,
                              view_name=VIEW_NAME_TARGET,
                              MDX=mdx_output)
        self.tm1.cubes.views.create(view=view_output, private=False)
        # execute method
        stdev_p(tm1_services={"tm1srv01": self.tm1},
                tm1_target="tm1srv01",
                cube_target=CUBE_NAME_TARGET,
                view_target=VIEW_NAME_TARGET,
                values=STDEV_INPUT_VALUES,
                tidy=False)
        # do check
        result = next(
            self.tm1.cubes.cells.execute_view_values(
                cube_name=CUBE_NAME_TARGET,
                view_name=VIEW_NAME_TARGET,
                private=False))
        self.assertAlmostEqual(result,
                               STDEV_P_EXPECTED_RESULT,
                               delta=STDEV_TOLERANCE)

    def test_tm1tidy_true_input_view_output_view(self):
        # create source_view
        mdx_input = MDX_TEMPLATE_SHORT.format(
            rows="{ HEAD ( { [" + DIMENSION_NAMES[0] + "].Members}," +
            str(len(STDEV_INPUT_VALUES)) + ") }",
            columns="{[" + DIMENSION_NAMES[1] + "].[Element_1]}",
            cube=CUBE_NAME_SOURCE)
        view_input = MDXView(cube_name=CUBE_NAME_SOURCE,
                             view_name=VIEW_NAME_SOURCE,
                             MDX=mdx_input)
        self.tm1.cubes.views.create(view=view_input, private=False)
        # create target_view
        mdx_output = MDX_TEMPLATE_SHORT.format(
            rows="{[" + DIMENSION_NAMES[0] + "].[Element_1]}",
            columns="{[" + DIMENSION_NAMES[1] + "].[Element_1]}",
            cube=CUBE_NAME_TARGET)
        view_output = MDXView(cube_name=CUBE_NAME_TARGET,
                              view_name=VIEW_NAME_TARGET,
                              MDX=mdx_output)
        self.tm1.cubes.views.create(view=view_output, private=False)
        # write values into input view
        mdx = view_input.MDX
        self.tm1.cubes.cells.write_values_through_cellset(
            mdx, STDEV_INPUT_VALUES)
        # execute method
        stdev(tm1_services={
            "tm1srv01": self.tm1,
            "tm1srv02": self.tm1
        },
              tm1_source="tm1srv01",
              tm1_target="tm1srv02",
              cube_source=CUBE_NAME_SOURCE,
              cube_target=CUBE_NAME_TARGET,
              view_source=VIEW_NAME_SOURCE,
              view_target=VIEW_NAME_TARGET,
              tidy=True)
        # check existence
        self.assertFalse(
            self.tm1.cubes.views.exists(cube_name=CUBE_NAME_SOURCE,
                                        view_name=VIEW_NAME_SOURCE,
                                        private=False))
        self.assertFalse(
            self.tm1.cubes.views.exists(cube_name=CUBE_NAME_TARGET,
                                        view_name=VIEW_NAME_TARGET,
                                        private=False))

    def test_tm1tidy_false_input_view_output_view(self):
        # define input view
        mdx_input = MDX_TEMPLATE_SHORT.format(
            rows="{ HEAD ( { [" + DIMENSION_NAMES[0] + "].Members}," +
            str(len(STDEV_INPUT_VALUES)) + ") }",
            columns="{[" + DIMENSION_NAMES[1] + "].[Element_1]}",
            cube=CUBE_NAME_SOURCE)
        view_input = MDXView(cube_name=CUBE_NAME_SOURCE,
                             view_name=VIEW_NAME_SOURCE,
                             MDX=mdx_input)
        self.tm1.cubes.views.create(view=view_input, private=False)
        # define output view
        mdx_output = MDX_TEMPLATE_SHORT.format(
            rows="{[" + DIMENSION_NAMES[0] + "].[Element_1]}",
            columns="{[" + DIMENSION_NAMES[1] + "].[Element_1]}",
            cube=CUBE_NAME_TARGET)
        view_output = MDXView(cube_name=CUBE_NAME_TARGET,
                              view_name=VIEW_NAME_TARGET,
                              MDX=mdx_output)
        self.tm1.cubes.views.create(view=view_output, private=False)
        # write values into input view
        mdx = view_input.MDX
        self.tm1.cubes.cells.write_values_through_cellset(
            mdx, STDEV_INPUT_VALUES)
        # execute method
        stdev(tm1_services={"tm1srv01": self.tm1},
              tm1_source="tm1srv01",
              cube_source=CUBE_NAME_SOURCE,
              view_source=VIEW_NAME_SOURCE,
              tidy=False)
        # check existence
        self.assertTrue(
            self.tm1.cubes.views.exists(cube_name=CUBE_NAME_SOURCE,
                                        view_name=VIEW_NAME_SOURCE,
                                        private=False))
        self.assertTrue(
            self.tm1.cubes.views.exists(cube_name=CUBE_NAME_TARGET,
                                        view_name=VIEW_NAME_TARGET,
                                        private=False))

    def test_tm1tidy_true_input_view(self):
        # define input view and output view
        mdx_input = MDX_TEMPLATE_SHORT.format(
            rows="{ HEAD ( { [" + DIMENSION_NAMES[0] + "].Members}," +
            str(len(STDEV_INPUT_VALUES)) + ") }",
            columns="{[" + DIMENSION_NAMES[1] + "].[Element_1]}",
            cube=CUBE_NAME_SOURCE)
        view_input = MDXView(cube_name=CUBE_NAME_SOURCE,
                             view_name=VIEW_NAME_SOURCE,
                             MDX=mdx_input)
        self.tm1.cubes.views.create(view=view_input, private=False)
        # write values into input view
        mdx = view_input.MDX
        self.tm1.cubes.cells.write_values_through_cellset(
            mdx, STDEV_INPUT_VALUES)
        # execute method
        stdev(tm1_services={"tm1srv01": self.tm1},
              tm1_source="tm1srv01",
              cube_source=CUBE_NAME_SOURCE,
              view_source=VIEW_NAME_SOURCE,
              tidy=True)
        # check existence
        self.assertFalse(
            self.tm1.cubes.views.exists(cube_name=CUBE_NAME_SOURCE,
                                        view_name=VIEW_NAME_SOURCE,
                                        private=False))

    def test_tm1tidy_false_input_view(self):
        # define input view and output view
        mdx_input = MDX_TEMPLATE_SHORT.format(
            rows="{ HEAD ( { [" + DIMENSION_NAMES[0] + "].Members}," +
            str(len(STDEV_INPUT_VALUES)) + ") }",
            columns="{[" + DIMENSION_NAMES[1] + "].[Element_1]}",
            cube=CUBE_NAME_SOURCE)
        view_input = MDXView(cube_name=CUBE_NAME_SOURCE,
                             view_name=VIEW_NAME_SOURCE,
                             MDX=mdx_input)
        self.tm1.cubes.views.create(view=view_input, private=False)
        # write values into input view
        mdx = view_input.MDX
        self.tm1.cubes.cells.write_values_through_cellset(
            mdx, STDEV_INPUT_VALUES)
        # execute method
        stdev_p(tm1_services={"tm1srv01": self.tm1},
                tm1_source="tm1srv01",
                cube_source=CUBE_NAME_SOURCE,
                view_source=VIEW_NAME_SOURCE,
                tidy=False)
        self.assertTrue(
            self.tm1.cubes.views.exists(cube_name=CUBE_NAME_SOURCE,
                                        view_name=VIEW_NAME_SOURCE,
                                        private=False))

    def test_tm1tidy_true_input_values_output_view(self):
        # define output view
        mdx_output = MDX_TEMPLATE_SHORT.format(
            rows="{[" + DIMENSION_NAMES[0] + "].[Element_1]}",
            columns="{[" + DIMENSION_NAMES[1] + "].[Element_1]}",
            cube=CUBE_NAME_TARGET)
        view_output = MDXView(cube_name=CUBE_NAME_TARGET,
                              view_name=VIEW_NAME_TARGET,
                              MDX=mdx_output)
        self.tm1.cubes.views.create(view=view_output, private=False)
        # execute method
        stdev(tm1_services={"tm1srv01": self.tm1},
              tm1_target="tm1srv01",
              cube_target=CUBE_NAME_TARGET,
              view_target=VIEW_NAME_TARGET,
              values=STDEV_INPUT_VALUES,
              tidy=True)
        # check view existence
        self.assertFalse(
            self.tm1.cubes.views.exists(cube_name=CUBE_NAME_TARGET,
                                        view_name=VIEW_NAME_TARGET,
                                        private=False))

    def test_tm1tidy_false_input_values_output_view(self):
        # define output view
        mdx_output = MDX_TEMPLATE_SHORT.format(
            rows="{[" + DIMENSION_NAMES[0] + "].[Element_1]}",
            columns="{[" + DIMENSION_NAMES[1] + "].[Element_1]}",
            cube=CUBE_NAME_TARGET)
        view_output = MDXView(cube_name=CUBE_NAME_TARGET,
                              view_name=VIEW_NAME_TARGET,
                              MDX=mdx_output)
        self.tm1.cubes.views.create(view=view_output, private=False)
        # execute method
        irr(tm1_services={"tm1srv01": self.tm1},
            tm1_target="tm1srv01",
            cube_target=CUBE_NAME_TARGET,
            view_target=VIEW_NAME_TARGET,
            values=IRR_INPUT_VALUES,
            tidy=False)
        # check view existence
        self.assertTrue(
            self.tm1.cubes.views.exists(cube_name=CUBE_NAME_TARGET,
                                        view_name=VIEW_NAME_TARGET,
                                        private=False))
Esempio n. 17
0
import time

from TM1py import TM1Service

ADDRESS = "localhost"
SSL = True
USER = "******"
PASSWORD = "******"

tm1_master = TM1Service(address=ADDRESS,
                        port=12354,
                        ssl=SSL,
                        user=USER,
                        password=PASSWORD)
tm1_other = TM1Service(address=ADDRESS,
                       port=12297,
                       ssl=SSL,
                       user=USER,
                       password=PASSWORD)

while True:
    dimension_master = tm1_master.dimensions.get(dimension_name="Region")
    dimension_other = tm1_other.dimensions.get(dimension_name="Region")

    if dimension_master != dimension_other:
        print(
            f"Recognized changes. Updating dimension: '{dimension_master.name}'"
        )
        tm1_other.dimensions.update(dimension_master)

    subsets_names = tm1_master.subsets.get_all_names("Region")
config = configparser.ConfigParser()
# storing the credentials in a file is not recommended for purposes other than testing.
# it's better to setup CAM with SSO or use keyring to store credentials in the windows credential manager. Sample:
# Samples/credentials_best_practice.py
config.read(r'..\config.ini')

mdx = """
SELECT
NON EMPTY {[Date].[2017-11-26], [Date].[2017-11-27]} * {[Bike Shares Measure].[Count]} ON ROWS,
NON EMPTY {[City].[NYC], [City].[Chicago]} ON COLUMNS
FROM [Bike Shares]
WHERE ([Version].[Actual])
"""

with TM1Service(**config['tm1srv01']) as tm1:
    pivot = tm1.cubes.cells.execute_mdx_dataframe_pivot(mdx=mdx)
    print(pivot)

view = NativeView(cube_name="Bike Shares",
                  view_name="Bike Shares By City",
                  suppress_empty_columns=True,
                  suppress_empty_rows=True)
view.add_row(dimension_name="Date",
             subset=AnonymousSubset(dimension_name="Date",
                                    expression="{Tm1SubsetAll([Date])}"))
view.add_row(dimension_name="Bike Shares Measure",
             subset=AnonymousSubset(dimension_name="Bike Shares Measure",
                                    elements=["Count"]))
view.add_column(dimension_name="City",
                subset=AnonymousSubset(dimension_name="City",
Esempio n. 19
0
def main(instance_name: str, view_name: str, executions: int, fast: bool):
    config = get_tm1_config()
    with TM1Service(**config[instance_name], session_context=APP_NAME) as tm1:
        model_cubes = filter(lambda c: not c.startswith("}"),
                             tm1.cubes.get_all_names())
        for cube_name in model_cubes:
            if not tm1.cubes.views.exists(cube_name, view_name, private=False):
                logging.info(
                    f"Skipping cube '{cube_name}' since view '{view_name}' does not exist"
                )
                continue

            original_vmm, original_vmt = retrieve_vmm_vmt(tm1, cube_name)
            write_vmm_vmt(tm1, cube_name, "1000000", "1000000")

            logging.info(f"Starting analysis for cube '{cube_name}'")
            original_dimension_order = tm1.cubes.get_storage_dimension_order(
                cube_name=cube_name)
            logging.info(
                f"Original dimension order for cube '{cube_name}' is '{original_dimension_order}'"
            )
            displayed_dimension_order = tm1.cubes.get_dimension_names(
                cube_name=cube_name)
            measure_dimension_only_numeric = is_dimension_only_numeric(
                tm1, original_dimension_order[-1])

            permutation_results = list()
            try:

                original_order = OriginalOrderExecutor(
                    tm1, cube_name, [view_name], displayed_dimension_order,
                    executions, measure_dimension_only_numeric,
                    original_dimension_order)
                permutation_results += original_order.execute(
                    reset_counter=True)

                main_executor = MainExecutor(tm1, cube_name, [view_name],
                                             displayed_dimension_order,
                                             executions,
                                             measure_dimension_only_numeric,
                                             fast)
                permutation_results += main_executor.execute()

                optimus_result = OptimusResult(cube_name, permutation_results)

                best_permutation = optimus_result.best_result
                logging.info(f"Completed analysis for cube '{cube_name}'")
                if not best_permutation:
                    logging.info(
                        f"No ideal dimension order found for cube '{cube_name}'."
                        f"Please pick manually based on csv and png results.")
                    return True

                best_order = best_permutation.dimension_order
                tm1.cubes.update_storage_dimension_order(cube_name, best_order)
                logging.info(
                    f"Updated dimension order for cube '{cube_name}' to {best_order}"
                )

            except:
                logging.error("Fatal error", exc_info=True)
                return False

            finally:
                with suppress(Exception):
                    write_vmm_vmt(tm1, cube_name, original_vmm, original_vmt)

                if len(permutation_results) > 0:
                    optimus_result = OptimusResult(cube_name,
                                                   permutation_results)
                    optimus_result.to_csv(
                        view_name,
                        RESULT_CSV.format(cube_name, view_name, TIME_STAMP))
                    optimus_result.to_png(
                        view_name,
                        RESULT_PNG.format(cube_name, view_name, TIME_STAMP))
    return True