Skip to content

CubeService

CubeService(rest)

Bases: ObjectService

Service to handle Object Updates for TM1 Cubes

Source code in TM1py/Services/CubeService.py
def __init__(self, rest: RestService):
    # to avoid Circular dependency of modules
    from TM1py.Services.AnnotationService import AnnotationService

    super().__init__(rest)
    self.cells = CellService(rest)
    self.views = ViewService(rest)
    self.annotations = AnnotationService(rest)

annotations = AnnotationService(rest) instance-attribute

cells = CellService(rest) instance-attribute

views = ViewService(rest) instance-attribute

check_rules(cube_name, **kwargs)

Check rules syntax for existing cube on TM1 Server

Parameters:

Name Type Description Default
cube_name str

name of a cube

required

Returns:

Type Description
Response

response

Source code in TM1py/Services/CubeService.py
def check_rules(self, cube_name: str, **kwargs) -> Response:
    """Check rules syntax for existing cube on TM1 Server

    :param cube_name: name of a cube
    :return: response
    """
    url = format_url("/Cubes('{}')/tm1.CheckRules", cube_name)

    response = self._rest.POST(url, **kwargs)
    errors = response.json()["value"]
    return errors

create(cube, **kwargs)

create new cube on TM1 Server

Parameters:

Name Type Description Default
cube Cube

instance of TM1py.Cube

required

Returns:

Type Description
Response

response

Source code in TM1py/Services/CubeService.py
def create(self, cube: Cube, **kwargs) -> Response:
    """create new cube on TM1 Server

    :param cube: instance of TM1py.Cube
    :return: response
    """
    url = "/Cubes"
    return self._rest.POST(url=url, data=cube.body, **kwargs)

cube_save_data(cube_name, **kwargs)

Serializes a cube by saving data updates

Parameters:

Name Type Description Default
cube_name str
required

Returns:

Type Description
Response

Response

Source code in TM1py/Services/CubeService.py
@require_data_admin
def cube_save_data(self, cube_name: str, **kwargs) -> Response:
    """Serializes a cube by saving data updates

    :param cube_name:
    :return: Response
    """
    from TM1py.Services import ProcessService

    ti = "CubeSaveData('{0}');".format(cube_name)
    process_service = ProcessService(self._rest)
    return process_service.execute_ti_code(ti, **kwargs)

delete(cube_name, **kwargs)

Delete a cube in TM1

Parameters:

Name Type Description Default
cube_name str
required

Returns:

Type Description
Response

response

Source code in TM1py/Services/CubeService.py
@require_data_admin
def delete(self, cube_name: str, **kwargs) -> Response:
    """Delete a cube in TM1

    :param cube_name:
    :return: response
    """
    url = format_url("/Cubes('{}')", cube_name)
    return self._rest.DELETE(url, **kwargs)

exists(cube_name, **kwargs)

Check if a cube exists. Return boolean.

Parameters:

Name Type Description Default
cube_name str
required

Returns:

Type Description
bool

Boolean

Source code in TM1py/Services/CubeService.py
def exists(self, cube_name: str, **kwargs) -> bool:
    """Check if a cube exists. Return boolean.

    :param cube_name:
    :return: Boolean
    """
    url = format_url("/Cubes('{}')", cube_name)
    return self._exists(url, **kwargs)

get(cube_name, **kwargs)

get cube from TM1 Server

Parameters:

Name Type Description Default
cube_name str
required

Returns:

Type Description
Cube

instance of TM1py.Cube

Source code in TM1py/Services/CubeService.py
def get(self, cube_name: str, **kwargs) -> Cube:
    """get cube from TM1 Server

    :param cube_name:
    :return: instance of TM1py.Cube
    """
    url = format_url("/Cubes('{}')?$expand=Dimensions($select=Name)", cube_name)
    response = self._rest.GET(url=url, **kwargs)
    cube = Cube.from_json(response.text)
    # cater for potential EnableSandboxDimension=T setup
    if case_and_space_insensitive_equals(cube.dimensions[0], "Sandboxes"):
        cube.dimensions = cube.dimensions[1:]
    return cube

get_all(**kwargs)

get all cubes from TM1 Server as TM1py.Cube instances

Returns:

Type Description
List[Cube]

List of TM1py.Cube instances

Source code in TM1py/Services/CubeService.py
def get_all(self, **kwargs) -> List[Cube]:
    """get all cubes from TM1 Server as TM1py.Cube instances

    :return: List of TM1py.Cube instances
    """
    url = "/Cubes?$expand=Dimensions($select=Name)"
    response = self._rest.GET(url, **kwargs)
    cubes = [Cube.from_dict(cube_as_dict=cube) for cube in response.json()["value"]]
    return cubes

get_all_names(skip_control_cubes=False, **kwargs)

Ask TM1 Server for list of all cube names

:skip_control_cubes: bool, True will exclude control cubes from list

Returns:

Type Description
List[str]

List of Strings

Source code in TM1py/Services/CubeService.py
def get_all_names(self, skip_control_cubes: bool = False, **kwargs) -> List[str]:
    """Ask TM1 Server for list of all cube names

    :skip_control_cubes: bool, True will exclude control cubes from list
    :return: List of Strings
    """
    url = format_url("/{}?$select=Name", "ModelCubes()" if skip_control_cubes else "Cubes")

    response = self._rest.GET(url, **kwargs)
    cubes = list(entry["Name"] for entry in response.json()["value"])
    return cubes

get_all_names_with_rules(skip_control_cubes=False, **kwargs)

Ask TM1 Server for list of all cube names that have rules

:skip_control_cubes: bool, True will exclude control cubes from list

Returns:

Type Description
List[str]

List of Strings

Source code in TM1py/Services/CubeService.py
def get_all_names_with_rules(self, skip_control_cubes: bool = False, **kwargs) -> List[str]:
    """Ask TM1 Server for list of all cube names that have rules

    :skip_control_cubes: bool, True will exclude control cubes from list
    :return: List of Strings
    """
    url = format_url(
        "/{}?$select=Name,Rules&$filter=Rules ne null", "ModelCubes()" if skip_control_cubes else "Cubes"
    )

    response = self._rest.GET(url, **kwargs)
    cubes = list(cube["Name"] for cube in response.json()["value"])
    return cubes

get_all_names_without_rules(skip_control_cubes=False, **kwargs)

Ask TM1 Server for list of all cube names that do not have rules :skip_control_cubes: bool, True will exclude control cubes from list

Returns:

Type Description
List[str]

List of Strings

Source code in TM1py/Services/CubeService.py
def get_all_names_without_rules(self, skip_control_cubes: bool = False, **kwargs) -> List[str]:
    """Ask TM1 Server for list of all cube names that do not have rules
    :skip_control_cubes: bool, True will exclude control cubes from list
    :return: List of Strings
    """

    url = format_url(
        "/{}?$select=Name,Rules&$filter=Rules eq null", "ModelCubes()" if skip_control_cubes else "Cubes"
    )

    response = self._rest.GET(url, **kwargs)
    cubes = list(cube["Name"] for cube in response.json()["value"])
    return cubes

get_control_cubes(**kwargs)

Get all Cubes with } prefix from TM1 Server as TM1py.Cube instances

Returns:

Type Description
List[Cube]

List of TM1py.Cube instances

Source code in TM1py/Services/CubeService.py
def get_control_cubes(self, **kwargs) -> List[Cube]:
    """Get all Cubes with } prefix from TM1 Server as TM1py.Cube instances

    :return: List of TM1py.Cube instances
    """
    url = "/ControlCubes()?$expand=Dimensions($select=Name)"
    response = self._rest.GET(url, **kwargs)
    cubes = [Cube.from_dict(cube_as_dict=cube) for cube in response.json()["value"]]
    return cubes

get_dimension_names(cube_name, skip_sandbox_dimension=True, **kwargs)

get name of the dimensions of a cube in their correct order

Parameters:

Name Type Description Default
cube_name str
required
skip_sandbox_dimension bool
True

Returns:

Type Description
List[str]

List : [dim1, dim2, dim3, etc.]

Source code in TM1py/Services/CubeService.py
def get_dimension_names(self, cube_name: str, skip_sandbox_dimension: bool = True, **kwargs) -> List[str]:
    """get name of the dimensions of a cube in their correct order

    :param cube_name:
    :param skip_sandbox_dimension:
    :return:  List : [dim1, dim2, dim3, etc.]
    """
    url = format_url("/Cubes('{}')/Dimensions?$select=Name", cube_name)
    response = self._rest.GET(url, **kwargs)
    dimension_names = [element["Name"] for element in response.json()["value"]]
    if skip_sandbox_dimension and dimension_names[0] == CellService.SANDBOX_DIMENSION:
        return dimension_names[1:]
    return dimension_names

get_last_data_update(cube_name, **kwargs)

Source code in TM1py/Services/CubeService.py
def get_last_data_update(self, cube_name: str, **kwargs) -> str:
    url = format_url("/Cubes('{}')/LastDataUpdate/$value", cube_name)
    response = self._rest.GET(url=url, **kwargs)
    return response.text

get_measure_dimension(cube_name, **kwargs)

Source code in TM1py/Services/CubeService.py
def get_measure_dimension(self, cube_name: str, **kwargs) -> str:
    url = format_url("/Cubes('{}')/Dimensions?$select=Name", cube_name)
    response = self._rest.GET(url, **kwargs)
    return response.json()["value"][-1]["Name"]

get_model_cubes(**kwargs)

Get all Cubes without } prefix from TM1 Server as TM1py.Cube instances

Returns:

Type Description
List[Cube]

List of TM1py.Cube instances

Source code in TM1py/Services/CubeService.py
def get_model_cubes(self, **kwargs) -> List[Cube]:
    """Get all Cubes without } prefix from TM1 Server as TM1py.Cube instances

    :return: List of TM1py.Cube instances
    """
    url = "/ModelCubes()?$expand=Dimensions($select=Name)"
    response = self._rest.GET(url, **kwargs)
    cubes = [Cube.from_dict(cube_as_dict=cube) for cube in response.json()["value"]]
    return cubes

get_number_of_cubes(skip_control_cubes=False, **kwargs)

Ask TM1 Server for count of cubes

:skip_control_cubes: bool, True will exclude control cubes from count

Returns:

Type Description
int

int, count

Source code in TM1py/Services/CubeService.py
def get_number_of_cubes(self, skip_control_cubes: bool = False, **kwargs) -> int:
    """Ask TM1 Server for count of cubes

    :skip_control_cubes: bool, True will exclude control cubes from count
    :return: int, count
    """
    if skip_control_cubes:
        response = self._rest.GET(url=format_url("/ModelCubes()?$select=Name&$top=0&$count"), **kwargs)
        return int(response.json()["@odata.count"])

    return int(self._rest.GET(url=format_url("/Cubes/$count"), **kwargs).text)

get_random_intersection(cube_name, unique_names=False)

Get a random Intersection in a cube used mostly for regression testing. Not optimized, in terms of performance. Function Loads ALL elements for EACH dim...

Parameters:

Name Type Description Default
cube_name str
required
unique_names bool

unique names instead of plain element names

False

Returns:

Type Description
List[str]

List of elements

Source code in TM1py/Services/CubeService.py
def get_random_intersection(self, cube_name: str, unique_names: bool = False) -> List[str]:
    """Get a random Intersection in a cube
    used mostly for regression testing.
    Not optimized, in terms of performance. Function Loads ALL elements for EACH dim...

    :param cube_name:
    :param unique_names: unique names instead of plain element names
    :return: List of elements
    """
    from TM1py.Services import DimensionService

    dimension_service = DimensionService(self._rest)
    dimensions = self.get_dimension_names(cube_name)
    elements = []
    for dimension in dimensions:
        hierarchy = dimension_service.get(dimension).default_hierarchy
        element = random.choice(list((hierarchy.elements.keys())))
        if unique_names:
            element = "[{}].[{}]".format(dimension, element)
        elements.append(element)
    return elements

get_storage_dimension_order(cube_name, **kwargs)

Get the storage dimension order of a cube

Parameters:

Name Type Description Default
cube_name str
required

Returns:

Type Description
List[str]

List of dimension names

Source code in TM1py/Services/CubeService.py
@require_version(version="11.4")
def get_storage_dimension_order(self, cube_name: str, **kwargs) -> List[str]:
    """Get the storage dimension order of a cube

    :param cube_name:
    :return: List of dimension names
    """
    url = format_url("/Cubes('{}')/tm1.DimensionsStorageOrder()?$select=Name", cube_name)
    response = self._rest.GET(url, **kwargs)
    return [dimension["Name"] for dimension in response.json()["value"]]

get_vmm(cube_name)

Source code in TM1py/Services/CubeService.py
@require_data_admin
@require_version(version="11.8.20")
def get_vmm(self, cube_name: str):
    url = format_url("/Cubes('{}')?$select=ViewStorageMaxMemory", cube_name)
    response = self._rest.GET(url)
    return response.json()["ViewStorageMaxMemory"]

get_vmt(cube_name)

Source code in TM1py/Services/CubeService.py
@require_data_admin
@require_version(version="11.8.20")
def get_vmt(self, cube_name: str):
    url = format_url("/Cubes('{}')?$select=ViewStorageMinTime", cube_name)
    response = self._rest.GET(url)
    return response.json()["ViewStorageMinTime"]

load(cube_name, **kwargs)

Load the cube into memory on the server

Parameters:

Name Type Description Default
cube_name str
required

Returns:

Type Description
Response
Source code in TM1py/Services/CubeService.py
@require_data_admin
@require_version(version="11.6")
def load(self, cube_name: str, **kwargs) -> Response:
    """Load the cube into memory on the server

    :param cube_name:
    :return:
    """
    url = format_url("/Cubes('{}')/tm1.Load", cube_name)
    return self._rest.POST(url=url, **kwargs)

lock(cube_name, **kwargs)

Locks the cube to prevent any users from modifying it

Parameters:

Name Type Description Default
cube_name str
required

Returns:

Type Description
Response
Source code in TM1py/Services/CubeService.py
def lock(self, cube_name: str, **kwargs) -> Response:
    """Locks the cube to prevent any users from modifying it

    :param cube_name:
    :return:
    """
    url = format_url("/Cubes('{}')/tm1.Lock", cube_name)
    return self._rest.POST(url=url, **kwargs)

search_for_dimension(dimension_name, skip_control_cubes=False, **kwargs)

Ask TM1 Server for list of cube names that contain specific dimension

Parameters:

Name Type Description Default
dimension_name str

string, valid dimension name (case insensitive)

required
skip_control_cubes bool

bool, True will exclude control cubes from result

False
Source code in TM1py/Services/CubeService.py
def search_for_dimension(self, dimension_name: str, skip_control_cubes: bool = False, **kwargs) -> List[str]:
    """Ask TM1 Server for list of cube names that contain specific dimension

    :param dimension_name: string, valid dimension name (case insensitive)
    :param skip_control_cubes: bool, True will exclude control cubes from result
    """
    url = format_url(
        "/{}?$select=Name&$filter=Dimensions/any(d: replace(tolower(d/Name), ' ', '') eq '{}')",
        "ModelCubes()" if skip_control_cubes else "Cubes",
        dimension_name.lower().replace(" ", ""),
    )
    response = self._rest.GET(url, **kwargs)
    cubes = list(entry["Name"] for entry in response.json()["value"])
    return cubes

search_for_dimension_substring(substring, skip_control_cubes=False, **kwargs)

Ask TM1 Server for a dictinary of cube names with the dimension whose name contains the substring

Parameters:

Name Type Description Default
substring str

string to search for in dim name

required
skip_control_cubes bool

bool, True will exclude control cubes from result

False
Source code in TM1py/Services/CubeService.py
def search_for_dimension_substring(
    self, substring: str, skip_control_cubes: bool = False, **kwargs
) -> Dict[str, List[str]]:
    """Ask TM1 Server for a dictinary of cube names with the dimension whose name contains the substring

    :param substring: string to search for in dim name
    :param skip_control_cubes: bool, True will exclude control cubes from result
    """
    substring = substring.lower().replace(" ", "")

    url = format_url(
        "/{}?$select=Name&$filter=Dimensions/any(d: contains(replace(tolower(d/Name), ' ', ''),'{}'))"
        + "&$expand=Dimensions($select=Name;$filter=contains(replace(tolower(Name), ' ', ''), '{}'))",
        "ModelCubes()" if skip_control_cubes else "Cubes",
        substring,
        substring,
    )

    response = self._rest.GET(url, **kwargs)
    cube_dict = {entry["Name"]: [dim["Name"] for dim in entry["Dimensions"]] for entry in response.json()["value"]}
    return cube_dict

search_for_rule_substring(substring, skip_control_cubes=False, case_insensitive=True, space_insensitive=True, **kwargs)

get all cubes from TM1 Server as TM1py.Cube instances where rules for given cube contain specified substring

Parameters:

Name Type Description Default
substring str

string to search for in rules

required
skip_control_cubes bool

bool, True will exclude control cubes from result

False
case_insensitive

case agnostic search

True
space_insensitive

space agnostic search

True

Returns:

Type Description
List[Cube]

List of TM1py.Cube instances

Source code in TM1py/Services/CubeService.py
def search_for_rule_substring(
    self, substring: str, skip_control_cubes: bool = False, case_insensitive=True, space_insensitive=True, **kwargs
) -> List[Cube]:
    """get all cubes from TM1 Server as TM1py.Cube instances where rules for given cube contain specified substring

    :param substring: string to search for in rules
    :param skip_control_cubes: bool, True will exclude control cubes from result
    :param case_insensitive: case agnostic search
    :param space_insensitive: space agnostic search
    :return: List of TM1py.Cube instances
    """
    substring = substring.lower().replace(" ", "")

    url_filter = "Rules ne null and contains("
    if case_insensitive and space_insensitive:
        url_filter += format_url("tolower(replace(Rules, ' ', '')),'{}')", substring)
    elif case_insensitive:
        url_filter += format_url("tolower(Rules),'{}')", substring)
    elif space_insensitive:
        url_filter += format_url("replace(Rules, ' ', ''),'{}')", substring)
    else:
        url_filter += format_url("Rules,'{}')", substring)

    url = (
        f"/{'ModelCubes()' if skip_control_cubes else 'Cubes'}?$filter={url_filter}"
        f"&$expand=Dimensions($select=Name)"
    )

    response = self._rest.GET(url, **kwargs)
    cubes = [Cube.from_dict(cube_as_dict=cube) for cube in response.json()["value"]]
    return cubes

set_vmm(cube_name, vmm)

Source code in TM1py/Services/CubeService.py
@require_data_admin
@require_version(version="11.8.20")
def set_vmm(self, cube_name: str, vmm: int):
    url = format_url("/Cubes('{}')", cube_name)
    payload = {"ViewStorageMaxMemory": vmm}
    self._rest.PATCH(url=url, data=json.dumps(payload))

set_vmt(cube_name, vmt)

Source code in TM1py/Services/CubeService.py
@require_data_admin
@require_version(version="11.8.20")
def set_vmt(self, cube_name: str, vmt: int):
    url = format_url("/Cubes('{}')", cube_name)
    payload = {"ViewStorageMinTime": vmt}
    self._rest.PATCH(url=url, data=json.dumps(payload))

unload(cube_name, **kwargs)

Unload the cube from memory

Parameters:

Name Type Description Default
cube_name str
required

Returns:

Type Description
Response
Source code in TM1py/Services/CubeService.py
@require_data_admin
@require_version(version="11.6")
def unload(self, cube_name: str, **kwargs) -> Response:
    """Unload the cube from memory

    :param cube_name:
    :return:
    """
    url = format_url("/Cubes('{}')/tm1.Unload", cube_name)
    return self._rest.POST(url=url, **kwargs)

unlock(cube_name, **kwargs)

Unlocks the cube to allow modifications

Parameters:

Name Type Description Default
cube_name str
required

Returns:

Type Description
Response
Source code in TM1py/Services/CubeService.py
def unlock(self, cube_name: str, **kwargs) -> Response:
    """Unlocks the cube to allow modifications

    :param cube_name:
    :return:
    """
    url = format_url("/Cubes('{}')/tm1.Unlock", cube_name)
    return self._rest.POST(url=url, **kwargs)

update(cube, **kwargs)

Update existing cube on TM1 Server

Parameters:

Name Type Description Default
cube Cube

instance of TM1py.Cube

required

Returns:

Type Description
Response

response

Source code in TM1py/Services/CubeService.py
def update(self, cube: Cube, **kwargs) -> Response:
    """Update existing cube on TM1 Server

    :param cube: instance of TM1py.Cube
    :return: response
    """
    url = format_url("/Cubes('{}')", cube.name)
    return self._rest.PATCH(url, cube.body, **kwargs)

update_or_create(cube, **kwargs)

update if exists else create

Parameters:

Name Type Description Default
cube Cube
required

Returns:

Type Description
Response
Source code in TM1py/Services/CubeService.py
def update_or_create(self, cube: Cube, **kwargs) -> Response:
    """update if exists else create

    :param cube:
    :return:
    """
    if self.exists(cube_name=cube.name, **kwargs):
        return self.update(cube=cube, **kwargs)

    return self.create(cube=cube, **kwargs)

update_or_create_rules(cube_name, rules, **kwargs)

Update if exists, else create rules from a TM1 Server cube

Parameters:

Name Type Description Default
cube_name str

name of a cube

required
rules Union[str, Rules]

rules content

required

Returns:

Type Description
Response

response

Source code in TM1py/Services/CubeService.py
def update_or_create_rules(self, cube_name: str, rules: Union[str, Rules], **kwargs) -> Response:
    """Update if exists, else create rules from a TM1 Server cube

    :param cube_name: name of a cube
    :param rules: rules content
    :return: response
    """
    if isinstance(rules, str):
        rules = Rules(rules=rules)
    if not isinstance(rules, Rules):
        raise ValueError("rules must be type str or Rules")

    url = format_url("/Cubes('{}')", cube_name)
    response = self._rest.PATCH(url=url, data=rules.body, **kwargs)
    return response

update_storage_dimension_order(cube_name, dimension_names)

Update the storage dimension order of a cube

Parameters:

Name Type Description Default
cube_name str
required
dimension_names Iterable[str]
required

Returns:

Type Description
float

Float: -23.076489699337078 (percent change in memory usage)

Source code in TM1py/Services/CubeService.py
@require_data_admin
@require_version(version="11.4")
def update_storage_dimension_order(self, cube_name: str, dimension_names: Iterable[str]) -> float:
    """Update the storage dimension order of a cube

    :param cube_name:
    :param dimension_names:
    :return:  Float: -23.076489699337078 (percent change in memory usage)
    """
    url = format_url("/Cubes('{}')/tm1.ReorderDimensions", cube_name)
    payload = dict()
    payload["Dimensions@odata.bind"] = [format_url("Dimensions('{}')", dimension) for dimension in dimension_names]
    response = self._rest.POST(url=url, data=json.dumps(payload))
    return response.json()["value"]