def run_test_folder_application(self, private): app = FolderApplication(TM1PY_APP_FOLDER, "not_relevant") self.tm1.applications.create(application=app, private=private) app_retrieved = self.tm1.applications.get(app.path, app.application_type, app.name, private=private) self.assertEqual(app, app_retrieved) exists = self.tm1.applications.exists( app.path, name=app.name, application_type=ApplicationTypes.FOLDER, private=private) self.assertTrue(exists) self.tm1.applications.delete(app.path, app.application_type, app.name, private=private) exists = self.tm1.applications.exists( app.path, name=app.name, application_type=ApplicationTypes.FOLDER, private=private) self.assertFalse(exists)
def run_folder_application(self, private): app = FolderApplication(self.tm1py_app_folder, "not_relevant") self.tm1.applications.create(application=app, private=private) app_retrieved = self.tm1.applications.get(app.path, app.application_type, app.name, private=private) self.assertEqual(app, app_retrieved) exists = self.tm1.applications.exists( app.path, name=app.name, application_type=ApplicationTypes.FOLDER, private=private) self.assertTrue(exists) self.tm1.applications.rename(app.path, application_type=ApplicationTypes.FOLDER, application_name=app.name, new_application_name=app.name + self.rename_suffix, private=private) exists = self.tm1.applications.exists( app.path, name=app.name, application_type=ApplicationTypes.FOLDER, private=private) self.assertFalse(exists) exists = self.tm1.applications.exists( app.path, name=app.name + self.rename_suffix, application_type=ApplicationTypes.FOLDER, private=private) self.assertTrue(exists) self.tm1.applications.delete(app.path, app.application_type, app.name + self.rename_suffix, private=private) exists = self.tm1.applications.exists( app.path, name=app.name + self.rename_suffix, application_type=ApplicationTypes.FOLDER, private=private) self.assertFalse(exists)
def get(self, path: str, application_type: Union[str, ApplicationTypes], name: str, private: bool = False, **kwargs) -> Application: """ Retrieve Planning Analytics Application :param path: path with forward slashes :param application_type: str or ApplicationType from Enum :param name: :param private: :return: """ # raise ValueError if not a valid ApplicationType application_type = ApplicationTypes(application_type) # documents require special treatment if application_type == ApplicationTypes.DOCUMENT: return self.get_document(path=path, name=name, private=private, **kwargs) if not application_type == ApplicationTypes.FOLDER: name += application_type.suffix contents = 'PrivateContents' if private else 'Contents' mid = "" if path.strip() != '': mid = "".join([ format_url("/Contents('{}')", element) for element in path.split('/') ]) base_url = format_url("/api/v1/Contents('Applications')" + mid + "/" + contents + "('{application_name}')", application_name=name) if application_type == ApplicationTypes.CUBE: response = self._rest.GET(url=base_url + "?$expand=Cube($select=Name)", **kwargs) return CubeApplication(path=path, name=name, cube_name=response.json()["Cube"]["Name"]) elif application_type == ApplicationTypes.CHORE: response = self._rest.GET(url=base_url + "?$expand=Chore($select=Name)", **kwargs) return ChoreApplication( path=path, name=name, chore_name=response.json()["Chore"]["Name"]) elif application_type == ApplicationTypes.DIMENSION: response = self._rest.GET(url=base_url + "?$expand=Dimension($select=Name)", **kwargs) return DimensionApplication( path=path, name=name, dimension_name=response.json()["Dimension"]["Name"]) elif application_type == ApplicationTypes.FOLDER: # implicit TM1pyException if application doesn't exist self._rest.GET(url=base_url, **kwargs) return FolderApplication(path=path, name=name) elif application_type == ApplicationTypes.LINK: # implicit TM1pyException if application doesn't exist self._rest.GET(url=base_url, **kwargs) response = self._rest.GET(base_url + "?$expand=*", **kwargs) return LinkApplication(path=path, name=name, url=response.json()["URL"]) elif application_type == ApplicationTypes.PROCESS: response = self._rest.GET(url=base_url + "?$expand=Process($select=Name)", **kwargs) return ProcessApplication( path=path, name=name, process_name=response.json()["Process"]["Name"]) elif application_type == ApplicationTypes.SUBSET: url = "".join([ base_url, "?$expand=Subset($select=Name;$expand=Hierarchy($select=Name;$expand=Dimension($select=Name)))" ]) response = self._rest.GET(url=url, **kwargs) return SubsetApplication( path=path, name=name, dimension_name=response.json()["Subset"]["Hierarchy"] ["Dimension"]["Name"], hierarchy_name=response.json()["Subset"]["Hierarchy"]["Name"], subset_name=response.json()["Subset"]["Name"]) elif application_type == ApplicationTypes.VIEW: response = self._rest.GET( url=base_url + "?$expand=View($select=Name;$expand=Cube($select=Name))", **kwargs) return ViewApplication( path=path, name=name, cube_name=response.json()["View"]["Cube"]["Name"], view_name=response.json()["View"]["Name"])
def setUpClass(cls) -> None: # 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)
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 cls.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(cls.cube_name, cls.dimension_names) if not cls.tm1.cubes.exists(cls.cube_name): cls.tm1.cubes.create(cube) # Build cube view view = NativeView(cube_name=cls.cube_name, view_name=cls.view_name, suppress_empty_columns=True, suppress_empty_rows=True) view.add_row( dimension_name=cls.dimension_names[0], subset=AnonymousSubset(dimension_name=cls.dimension_names[0], expression='{[' + cls.dimension_names[0] + '].Members}')) view.add_row( dimension_name=cls.dimension_names[1], subset=AnonymousSubset(dimension_name=cls.dimension_names[1], expression='{[' + cls.dimension_names[1] + '].Members}')) view.add_column( dimension_name=cls.dimension_names[2], subset=AnonymousSubset(dimension_name=cls.dimension_names[2], expression='{[' + cls.dimension_names[2] + '].Members}')) if not cls.tm1.cubes.views.exists( cls.cube_name, view.name, private=False): cls.tm1.cubes.views.create(view=view, private=False) # Build subset subset = Subset(cls.subset_name, cls.dimension_names[0], cls.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=cls.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=cls.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, cls.process_name, parameters=[{ 'Name': 'pRegion', 'Value': 'UK' }]) ]) cls.tm1.chores.create(c1) # create Folder app = FolderApplication("", cls.tm1py_app_folder) cls.tm1.applications.create(application=app, private=False)
def get(self, path, application_type, name, private=False): """ Retrieve Planning Analytics Application :param path: :param application_type: :param name: :param private: :return: """ # raise ValueError if not a valid ApplicationType application_type = ApplicationTypes(application_type) # documents require special treatment if application_type == ApplicationTypes.DOCUMENT: return self.get_document(path=path, name=name, private=private) if not application_type == ApplicationTypes.FOLDER: name += application_type.suffix contents = 'PrivateContents' if private else 'Contents' mid = "" if path.strip() != '': mid = "".join([ "/Contents('{}')".format(element) for element in path.split('/') ]) base_url = "/api/v1/Contents('Applications'){dynamic_mid}/{contents}('{application_name}')".format( dynamic_mid=mid, contents=contents, application_name=name) if application_type == ApplicationTypes.CUBE: response = self._rest.GET(base_url + "?$expand=Cube($select=Name)") return CubeApplication(path=path, name=name, cube_name=response.json()["Cube"]["Name"]) elif application_type == ApplicationTypes.CHORE: response = self._rest.GET(base_url + "?$expand=Chore($select=Name)") return ChoreApplication( path=path, name=name, chore_name=response.json()["Chore"]["Name"]) elif application_type == ApplicationTypes.DIMENSION: response = self._rest.GET(base_url + "?$expand=Dimension($select=Name)") return DimensionApplication( path=path, name=name, dimension_name=response.json()["Dimension"]["Name"]) elif application_type == ApplicationTypes.FOLDER: # implicit TM1pyException if doesn't exist self._rest.GET(base_url) return FolderApplication(path=path, name=name) elif application_type == ApplicationTypes.LINK: # implicit TM1pyException if doesn't exist self._rest.GET(base_url) response = self._rest.GET(base_url + "?$expand=*") return LinkApplication(path=path, name=name, url=response.json()["URL"]) elif application_type == ApplicationTypes.PROCESS: response = self._rest.GET(base_url + "?$expand=Process($select=Name)") return ProcessApplication( path=path, name=name, process_name=response.json()["Process"]["Name"]) elif application_type == ApplicationTypes.SUBSET: response = self._rest.GET( base_url + "?$expand=Subset($select=Name;$expand=Hierarchy($select=Name;$expand=Dimension($select=Name)))" ) return SubsetApplication( path=path, name=name, dimension_name=response.json()["Subset"]["Hierarchy"] ["Dimension"]["Name"], hierarchy_name=response.json()["Subset"]["Hierarchy"]["Name"], subset_name=response.json()["Subset"]["Name"]) elif application_type == ApplicationTypes.VIEW: response = self._rest.GET( base_url + "?$expand=View($select=Name;$expand=Cube($select=Name))") return ViewApplication( path=path, name=name, cube_name=response.json()["View"]["Cube"]["Name"], view_name=response.json()["View"]["Name"])