Skip to content

Releases: cubewise-code/tm1py

2.0

31 Jan 17:40
Compare
Choose a tag to compare

Highlights

1. Support for TM1 v12

TM1py now works with TM1 v12.

with TM1Service(
        address="us-east-2.aws.planninganalytics.ibm.com",
        api_key="AB4VfG7T8wPM-912uFKeYG5PGh0XbS80MVBAt7SEG6xn",
        iam_url="https://iam.cloud.ibm.com/identity/token",
        tenant="YA9A2T8BS2ZU",
        database="Database") as tm1:
    print(tm1.server.get_product_Version())

by @rclapp in #1000

2. CRUD operations to manage servers on v12

with ManageService(domain=domain, root_client=root_client, root_secret=root_secret) as manager:
   manager.create_database(instance_name="instance name",
                          database_name="database_name",
                          product_version="12.0.0",
                          number_replicas=1,
                          cpu_requests="1000m",
                          cpu_limits="2000m",
                          memory_limits="2G",
                          memory_requests="1G",
                          storage_size="20Gi")

   manager.scale_database(instance_name="instance name", database_name="database name", replicas=2)

   manager.create_database_backup(instance_name="instance name", 
                                 database_name="database name", 
                                 backup_set_name="my backup")

by @rclapp

3. Asynchronous execute_mdx functions

Speed up your MDX executions by assigning more than one worker-thread in TM1.

mdx = """
SELECT
{TM1SubsetAll([Big Dimension])} ON ROWS,
{TM1SubsetAll([Small Dimension])} ON COLUMNS
FROM [Big Cube]
"""

with TM1Service(**tm1params) as tm1:
    cells = tm1.cells.execute_mdx(
        mdx=mdx,
        # leverage 4 worker threads in TM1 for the extraction
        max_workers=4,
        # parallelization on rows axis
        async_axis=1)

by @vmitsenko in #935 and #1030

4. Hierarchy updates from data frames

Create and update TM1 hierarchies directly from pandas dataframes.

Stores ElementType Alias:a City:s Square Footage:n level001 level000 level001_weight level000_weight
S151 Numeric Boardwalk Games New York City 120 USA World 1 1
S143 Numeric Strategy Vault Zurich 250 Switzerland World 1 1
S811 Numeric Cardboard Castle Sydney 80 Sydney World 1 1
columns = ["Stores", "ElementType", "Alias:a", "City:s", "Square Footage:n", "level001",
           "level000", "level001_weight", "level000_weight"]
data = [
    ['S151', "Numeric", "Boardwalk Games", "New York City", 120, "USA", "World", 1, 1],
    ['S143', 'Numeric', "Strategy Vault", "Zurich", 250, "Switzerland", "World", 1, 1],
    ['S811', 'Numeric', "Cardboard Castle", "Sydney", 80, "Sydney", "World", 1, 1],
]

with TM1Service(**tm1params) as tm1:
    tm1.hierarchies.update_or_create_hierarchy_from_dataframe(
        dimension_name="Stores",
        hierarchy_name="Stores",
        df=DataFrame(data=data, columns=columns)
    )
image

by @MariusWirtz in #944 and #1011

New Features, Improvements, and Bugfixes

Stats

  • Contributors: 15
  • Commits: 178
  • Changed Files: 72
  • Added Lines: 7,205
  • Deleted Lines: 1,643

How to upgrade TM1py

pip install tm1py --upgrade

New Contributors

Full Changelog: 1.11.1...2.0

1.11.3

23 May 09:29
Compare
Choose a tag to compare

Fixes

  • Add proxies arg to TM1Service #911
  • Show parameters on decorated functions in PyCharm e.g. execute_mdx_dataframe #913
  • Cater to breaking in change in urllib3 2.0 release #918

1.11.1

19 Apr 07:24
Compare
Choose a tag to compare

What's Changed

Full Changelog: 1.11...1.11.1

1.11

14 Apr 14:14
Compare
Choose a tag to compare

Highlights

1. Improved performance #882, #885

With this release TM1py makes better use of existing capabilities in the TM1 server to handle large read and write operations.

The write function

Pass use_blob=True to the write or write_dataframe function to use the new optimized write mode.

with TM1Service(**params) as tm1:
    cells = {
        ('Actual', 'Germany', 'T Series 4.0 L Sedan', 'Units', 'Jan'): 1500,
        ('Actual', 'Germany', 'T Series 4.0 L Sedan', 'Units', 'Feb'): 2100,
        ('Actual', 'Germany', 'T Series 4.0 L Sedan', 'Units', 'Mar'): 1100
    }
    tm1.cells.write("SalesCube", cells, use_blob=True)

On a sample of 1 million cell updates, this performs on par with Turbo Integrator and up to 6x faster than the previous write function. #882 (comment)


The write_async function

The write_async function now makes use of use_blob by default. The number of parallel worker threads in TM1 can be controlled through the max_workers argument. A reasonable value for slice_size needs to be provided.

E.g. if you are expecting 1 million cell updates, a reasonable choice would be 10 for max_workers and 100000 for slice_size.

with TM1Service(**params) as tm1:
    tm1.cells.write_async(
        cube_name="SalesCube",
        cells=cells,
        slice_size=100_000,
        max_workers=10)

On a sample of 1 million cell updates, this performs ~5 times better than plain Turbo Integrator and ~5 times better than the previous write_async function. #882 (comment)


The execute_mdx_dataframe, execute_view_dataframe functions

Pass use_blob=True to the execute_mdx_dataframe, and execute_view_dataframe functions to use the new optimized read mode.

with TM1Service(**sdata_params) as tm1:
    df = tm1.cells.execute_view_dataframe(cube_name="Sales Cube", view_name="Default", private=False, use_blob=True)

On large data sets this performs 20% to 40% better. It also reduces the memory footprint by ~70%. #885 (comment)

2. New shaped argument in the execute_view_dataframe function #893

Pass shaped=True to the execute_mdx_dataframe, and execute_view_dataframe functions to retrieve the data frame in the original shape of the cube view.

image

with TM1Service(**sdata_params) as tm1:
    df = tm1.cells.execute_view_dataframe(
        cube_name="Sales Cube",
        view_name="Default",
        shaped=True,
        use_blob=True)
account1 Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
0 Gross Margin% 57.5155 56.4074 59.1279 59.5385 57.7353 57.1263 58.4302 59.7887 56.9305 56.9046 59.8059 56.2537
1 Price 19360 19532 19218.5 19631 19941 19870 19365 19216 19241 19099.5 19883.5 19432.5
2 Units 1 2 2 1 1 1 1 1 1 2 1 1
3 Sales 19.36 39.064 38.437 19.631 19.941 19.87 19.365 19.216 19.241 38.199 19.8835 19.4325
4 Variable Costs 8.225 17.029 15.71 7.943 8.428 8.519 8.05 7.727 8.287 16.462 7.992 8.501

Please note the months on the columns in the table above

3. Re-authenticate after session timeout #856

Now TM1py will re-authenticate and retry the operation once if the operation failed due to a session timeout.

This is helpful in situations where a TM1py script has been idle for a while and once it attempts to restart interaction with TM1 it fails due to a session timeout.

New Features, Improvements, and Bugfixes

  • Fully support TM1 sandbox functionality by @adscheevel in #844
  • Support use of alternate hierarchies in get_elements_dataframe function by @MariusWirtz in #876
  • Allow dtype to be inferred by pandas with argument infer_dtype in execute_mdx_dataframe_shaped by @Kevin-Dekker in #879

Acknowledgments

Big thanks to @cwffonseca, @Kevin-Dekker, and @adscheevel for contributing code to this release, and many others for reporting bugs and requesting new features.

How to upgrade TM1py

pip install tm1py --upgrade

Full Changelog: 1.10.2...1.11

1.10.2

19 Jan 10:53
Compare
Choose a tag to compare

What's Changed

New Contributors

Full Changelog: 1.10.1...1.10.2

1.10.1

24 Oct 10:15
Compare
Choose a tag to compare

Fixes issue #819 that was introduced with release 1.10

What's Changed

New Contributors

Full Changelog: 1.10.0...1.10.1

1.10.0

10 Oct 14:00
Compare
Choose a tag to compare

Highlights

Performance improvements on all major TM1 I/O functions.

from TM1py import TM1Service

with TM1Service(address="", port=12354, ssl=True, user="admin", password="") as tm1:

    df = tm1.cells.execute_view_dataframe(cube_name="Sales", view_name="Default", private=False)
Time State SalesMeasure Value
0 202001 CA Gross Margin 13924.8
1 202001 CA Revenue 41330.4
2 202001 CA COGS 27405.6
from TM1py import TM1Service

with TM1Service(base_url="https://localhost:12354", user="admin", password="") as tm1:

    cells = {
        ('Belgium', 'Actual', '2022', 'Apr', 'Revenue'): 10_000,
        ('Belgium', 'Actual', '2022', 'May', 'Revenue'): 15_000,
        ...
        ('Belgium', 'Actual', '2022', 'Jun', 'Revenue'): 20_000,
        ('Belgium', 'Actual', '2022', 'Apr', 'Revenue'): 45_000,
    }

    tm1.cells.write_async(cube_name="Sales", cells=cells, slice_size=32_000, max_workers=4,
                          measure_dimension_elements={'Revenue': 'Numeric'})

Full support for TM1's git deployment functionality. Including the TM1Project and deployment definitions.

with TM1Service(address="", port=11247, ssl=True, user="admin", password="") as tm1:

    project = TM1Project(name="Project Definition")

    dev_deployment = TM1ProjectDeployment(
        deployment_name="Dev",
        settings={"ServerName": "dev"})

    dev_deployment.add_task(TM1ProjectTask(
        task_name="Security Refresh",
        process="Bedrock.Security.Refresh"))

    dev_deployment.include_all_attribute_dimensions(tm1)
    dev_deployment.add_ignore(object_class="Cubes", object_name="*")

    project.add_deployment(deployment=dev_deployment)

    tm1.git.tm1project_put(project)

New and more efficient ways to query and control elements and hierarchies.

from TM1py import TM1Service

with TM1Service(base_url="https://localhost:12354", user="admin", password="") as tm1:

    # break edge as one tiny atomic operation
    tm1.elements.remove_edge(dimension_name="Region", hierarchy_name="Region", parent="EU", component="UK")

    # add new edge as one tiny atomic operation
    tm1.elements.add_edges(dimension_name="Region", hierarchy_name="Region", edges={("Other", "UK"): 1})
from TM1py import TM1Service

with TM1Service(base_url="https://localhost:12354", user="admin", password="") as tm1:

    is_parent = tm1.elements.element_is_parent(dimension_name="Region", hierarchy_name="Region", parent_name="Other",
                                               element_name="UK")

    is_ancestor = tm1.elements.element_is_ancestor(dimension_name="Region", hierarchy_name="Region",
                                                   element_name="Other", ancestor_name="UK")

Heaps of miscellaneous features, optimizations and improvements that make your life easier when doing TM1 with Python.

from TM1py import TM1Service

with TM1Service(base_url="https://localhost:12354", user="admin", password="") as tm1:

    process_names = tm1.processes.search_string_in_code(search_string="Sunrise", skip_control_processes=True)
from TM1py import TM1Service

with TM1Service(base_url="https://localhost:12354", user="admin", password="apple") as tm1:

    tm1.cubes.cube_save_data("Sales")

New Features and Improvements

  • Fix in set_time function in ChoreStartTime class to allow 0 values by @samuelko123 in #686
  • Add substitute_title function to MDXView by @MariusWirtz in #687
  • Add include_headers argument to extract_cellset_csv function by to @MariusWirtz in #689
  • Add remove_edge function to ElementService to break individual parent-child relationship in one operation by @MariusWirtz in #693
  • Fix bug to allow dimension creation from JSON file by @MariusWirtz in #698
  • Improve performance of critical build_cellset_from_pandas_dataframe function by @Kevin-Dekker in #695
  • Add get_parents function to ElementService. Allows retrieval of all parents for an element by @MariusWirtz in #699
  • Fix doubled double quotes issue in element names by @MariusWirtz in #704
  • Explicitly add elements to leaves hierarchy so solve #702 by @MariusWirtz in #703
  • Handle duplicates in write_dataframe appropriately by @MariusWirtz in #708 & #712
  • Accept str for rules update on Cube object by @MariusWirtz in #710
  • New search function to find substrings in Rules or Processes (e.g., search_string_in_code) by @adscheevel in #723
  • Fix write failure for element names with : by @MariusWirtz in #724
  • Add get_element_principal_name function by @MaaYuu in #731
  • Add get_ancestors, get_descendants functions on Hierarchy by @MariusWirtz in #732
  • Read 'NA' element name as a string instead of pandas NaN by @MariusWirtz in #739
  • Align float numbers intelligently when writing through unbound processes, to avoid "Number too big" TI errors during writeback, by @pbuncik in #749
  • Add functions to find views that contain a specified subset by @adscheevel in #751
  • Improve write_async performance by exposing measure_dimension_elements to write_async function by @MariusWirtz in #753
  • Introduce get_descendant_edges function in Hierarchy class by @skriptmeister42 in #760
  • Fix the update function in ApplicationService to use the update operation instead of the delete and recreate approach, to avoid breaking existing references of the application by @jrobinsonLOR in #762
  • Implement element_is_parent and element_is_ancestor by @rclapp in #767 and #771
  • Allow queries with selection on more than 3 axes in the execute_mdx function by @MariusWirtz in #777
  • Add support for trace_cell_calculation, trace_cell_feeders, and check_cell_feeders by @rclapp in #780
  • Add function create_many in AnnotationService to create many annotations in one operation by @MariusWirtz in #785
  • Add new element functions like get_consolidated_elements, get_parents_of_all_elements by @adscheevel in #792
  • Adjust TM1py to changes in mdxpy 0.4 by @MariusWirtz in #793
  • Handle TM1Project in the GitService by @nicolasbisurgi in #775 and #796
  • Refactor Breakpoints and introduce new debugging functionality by @adscheevel in #791
  • Allow alternative separators for elements in get_value and other functions by @tobiaskapser in #801 and #805
  • Use 100k max statements in write function with use_ti=True by @MariusWirtz in #808
  • Enable TCP keepalive option for long run requests by @macsir in #807
  • Additional features in ServerService : CubeSaveData and DeleteAllPersistentFeeders by @Mr-SabyasachiBose in #810

New Contributors

How to upgrade TM1py

To upgrade TM1py, just use the following command:

pip install TM1py --upgrade

Full Changelog: 1.9.0...1.10.0

1.9.0

07 Feb 21:39
Compare
Choose a tag to compare

Highlights

New optional use_iterative_json parameter in execute_mdx_dataframe/execute_view_dataframe functions #646, #612

This new feature allows TM1py to use iterative JSON parsing.

When use_iterative_json is True TM1py requires a significantly smaller memory footprint (down to ~ 20% of the original value) at an almost negligible cost of performance (single percentage digit):

from TM1py import TM1Service

with TM1Service(
        base_url="https://localhost:12354",
        user="admin",
        password="apple") as tm1:
    
    df = tm1.cells.execute_view_dataframe(cube_name="Sales", view_name="Very Large View", private=False,
                                          use_iterative_json=True)

This is a handy feature when dealing with large or very large data volumes (1M to 10M cells) in an environment with limited RAM.

New skip_non_updateable argument in write/write_dataframe functions #657

This optional argument to the write/write_dataframe functions asks TM1py to filter out cells that can not be updated before attempting to write. If not used, TM1py will fail with an error when attempting to write to rule-derived or consolidated cells.

from TM1py import TM1Service

with TM1Service(
        base_url="https://localhost:12354",
        user="admin",
        password="apple") as tm1:

    cells = {
        ('Belgium', 'Revenue', '2022', 'Apr', 'Revenue'): 10_000,
        ('Belgium', 'Revenue', '2022', 'May', 'Revenue'): 15_000,
        ('Belgium', 'Revenue', '2022', 'Jun', 'Revenue'): 20_000,
        ('Belgium', 'Revenue', '2022', 'Q1', 'Revenue'): 45_000,
    }

    tm1.cells.write("Sales", cells, skip_non_updateable=True)

This is a useful feature, as it saves the TM1py user from verifying the validity of the cell updates yourself when not working with flawless data sources.
Only errors w.r.t. updatability are suppressed! Attempts, for instance, to write to not existing elements will still raise errors.

New search functions to search through cubes, processes, and chores #660, #663, #665

from TM1py import TM1Service

with TM1Service(
        base_url="https://localhost:12354",
        user="admin",
        password="apple") as tm1:

    processes = tm1.processes.search_string_in_code(search_string="Sales")
from TM1py import TM1Service

with TM1Service(
        base_url="https://localhost:12354",
        user="admin",
        password="apple") as tm1:

    processes = tm1.processes.search_string_in_name(name_contains="Sales")
from TM1py import TM1Service

with TM1Service(
        base_url="https://localhost:12354",
        user="admin",
        password="apple") as tm1:

    cubes = tm1.cubes.search_for_dimension(dimension_name="Product", skip_control_cubes=True)

New Features

  • add write to_message_log_function #621
  • allow skip_zeros in execute_mdx_values function #659
  • use python built-in csv module to create csv strings in execute_mdx_csv function #678
  • new rename function in ApplicationService #682
  • support compact_json in some execute_mdx_ functions #650

Improvements and Bugfixes

  • get_last_message_from_processerrorlog to return text ac0d72f
  • raise exception when session creation fails a42753e
  • don't raise error if cellset is already deleted 3246391
  • improve execute_set_mdx function 61fe2ea
  • add update_or_create function for document from file 7f94f71
  • drop obsolete arguments in TM1Service constructor #652
  • support attribute type change #664
  • fix get_values function issue to work with alternate hierarchies seamlessly #680
  • improve handling of alternate hierarchies in write function #679
  • optional measure_dimension_elements dictionary argument to write and write_dataframe function to improve performance b21ac47

Acknowledgments

Big thanks to @rkvinoth, @jrobinsonAG, @gbryant-dev, @raeldor, @adscheevel, @jordanjeremy for contributing code to this release, and many others for reporting bugs and requesting new features.

How to upgrade TM1py

To upgrade TM1py, just use the following command:

pip install TM1py --upgrade

1.8.0

29 Sep 11:18
Compare
Choose a tag to compare

Highlights

  • Support MDX properties in execute_mdx_dataframe.
    This allows to query data and attribute data with a single query into one shared data frame.
from TM1py import TM1Service

with TM1Service(address="", port=12354, user="admin", password="apple", ssl=True) as tm1:
    mdx = """
    SELECT
    {Tm1SubsetAll([Region])} PROPERTIES [Region].[Currency] ON COLUMNS,
    {Tm1SubsetAll([Year])} ON ROWS
    FROM [Sales]
    """

    data = tm1.cells.execute_mdx_dataframe(mdx, include_attributes=True)
Year Region Currency Value
0 2021 US USD 18
1 2021 UK GBP 4
  • write_async and write_async_dataframe functions with max_workers argument.
    This is essentially an easy way to speed up TM1 writeback through parallelization.
from TM1py import TM1Service

with TM1Service(address="", port=12354, ssl=True, user="admin", password="apple") as tm1:
    cells = {
        ('e1', 'e1'): 1,
        ('e1', 'e2'): 2,
        ('e2', 'e1'): 3,
        ('e2', 'e2'): 4,
        ('e3', 'e1'): 5,
        ('e3', 'e2'): 6,
    }

    tm1.cells.write_async(cube_name="c1", cells=cells, slice_size=1, max_workers=6)
from pandas import DataFrame

from TM1py import TM1Service

with TM1Service(address="", port=12354, ssl=True, user="admin", password="apple") as tm1:
    data = DataFrame({
        'd1': ['e1', 'e1', 'e2', 'e2', 'e3', 'e3'],
        'd2': ['e1', 'e2', 'e1', 'e2', 'e1', 'e2'],
        'value': [1, 2, 3, 4, 5, 6],
    })

    tm1.cells.write_dataframe_async(cube_name="c1", data=data, slice_size_of_dataframe=1, max_workers=6)
  • TM1 git support #447
    TM1py now allows you to manage the TM1 git repository. You can manage the TM1 database with git and TM1py.

  • New authentication mode based on cam_passport. Can be used from Jupyter within Cognos Analytics.

from ca_data_connector.ca_lib import OnPremSession

session = OnPremSession()
session.initialize()
passport = session.get_cookies()['cam_passport']

with TM1Service(address=address, port=port, ssl=ssl, cam_passport=passport) as tm1:
    print(tm1.server.get_server_name())

New Features

  • AuditLog queries 3771dad
  • Changes to tm1.power_bi.execute_mdx function to provide data to PBI in the most friendly way #476
  • Improvement on PowerBI dimension retrieval function to fetch attribute for a parent instead of parent element name #478
  • Support MDX PROPERTIES in execute_mdx_dataframe #470
  • Introduce a new cancel_at_timeout argument to abort TM1 operation once the timeout is reached
  • Support process debugging a83da11
  • New arguments on execute_mdx, execute_view: skip_cell_properties, element_unique_names to control shape of response dictionary f751edf, 6d9e520
  • TM1 git support #447
  • New write_dataframe_async function 94081eb
  • New write_async function 3969c1d
  • Create, read, update, delete servers on admin host #296
  • New re_authenticate function in TM1Service 2028d3d
  • Better delta log requests aeed032
  • Allow login with cam_passport f070c06

Fixes

  • Never attempt to delete leaves hierarchy a0aa152
  • Make install with pandas work with zsh c458e40
  • Fix encoding of ui-data property 6438309
  • Fix deactivate / activate chore #515
  • Accept float as timeout 2d0c555
  • Fix is_admin property in User class d9ed1b2
  • Fix documentation on readthedocs
  • Remove linebreaks when writing with ti #568
  • Include empty strings suppression in extract_cellset_raw 01eb4a7
  • Allow parameters on unbound processes 144db38
  • Improve kwargs delegation through call stack ee70f54
  • Allow WITH MEMBERS combined with include_attributes=True in execute_mdx_dataframe function #593
  • Allow WITH MEMBERS combined with display_attribute=True in execute_mdx_dataframe_shaped function #593
  • Skip sandbox dimension in cubes.get #595

Acknowledgments

Big thanks to @lapstue, @kaleming, @beckyconning, @macsir, @jrobinsonAG, @tomasfelcman, @cwffonseca for contributing code to this release, and many others for reporting bugs and requesting features.

How to upgrade TM1py

To upgrade TM1py, just use the following command:

pip install TM1py --upgrade

1.6.0

22 Jan 09:40
Compare
Choose a tag to compare

Highlights

  • support for IntegratedSecurityMode3
tm1 = TM1Service(address=servername, port=instanceport, ssl=True, integrated_login=True)
  • faster write function
with TM1Service(address="", port=12354, ssl=True, user="admin", password="apple") as tm1:
    cells = dict()
    cells["e1", "e1"] = 1
    cells["e2", "e2"] = 2

    tm1.cells.write("c1", cells, use_ti=True)
  • new write_dataframe function 82a39bd
with TM1Service(address="", port=12354, ssl=True, user="admin", password="apple") as tm1:
    df = pd.DataFrame({
        'd1': ['e1', 'e2'],
        'd2': ['e1', 'e2'],
        'Value': [1, 2]})

    tm1.cells.write_dataframe('c1', df)
  • support for sandboxes
with TM1Service(address="", port=12354, ssl=True, user="admin", password="apple") as tm1:
    sandbox = Sandbox(name="My Sandbox")
    tm1.sandboxes.create(sandbox)
with TM1Service(address="", port=12354, ssl=True, user="admin", password="apple") as tm1:
    cube_name = 'c1'
    cells = {
        ("e1", "e1"): 1,
        ("e2", "e2"): 2
    }
    tm1.cells.write(cube_name, cells, sandbox_name="My Sandbox")
with TM1Service(address="", port=12354, ssl=True, user="admin", password="apple") as tm1:
    mdx = """
    SELECT
    {[d1].[e1], [d1].[e2]} ON ROWS,
    {[d2].[e1], [d2].[e2]} ON COLUMNS
    FROM [c1]
    """
    df = tm1.cells.execute_mdx_dataframe(mdx, sandbox_name="My Sandbox")
  • impersonation #353
with TM1Service(address="", port=12354, ssl=True, user="admin", password="apple", impersonate="Marius") as tm1:
    print(tm1.whoami)

New Features

  • new query options on filter_message_log function: level, msg_contains e9c2715
  • new direct functions to add elements, edges or element attributes quickly: add_elements, add_edges, add_element_attributes
  • new security functions: get_read_only_users, get_custom_security_groups, update_user_password #393
  • functions to start and stop performance monitor: start_performance_monitor, stop_performance_monitor
  • new cube_lock, cube_unlock functions 8ea0096
  • new remove_edges_under_consolidation function e5d2876
  • new get_elements_by_wildcard function e4837dc
  • add remove_all_elements, remove_all_edges function to hierarchy class
  • optional increment argument in write function
  • Add add_component function to Hierarchy class
  • support for changesets in write operations #454

Fixes

  • improved test suite #301
  • fix get_number_of_elements function
  • fix get_members_under_consolidation #381
  • make get_attribute_of_elements work with numeric attributes 39d61fe
  • avoid execute_dataframe method to fail over 0 cell 7450911
  • implement __sub__ function in CaseAndSpaceInsensitiveSet 8c807e7
  • issue in get_last_data_update function 9bc898e
  • Fix single-axis selection issue in execute_mdx #416
  • work around TM1 REST issue with RuleDerived cell property b5d4bd8
  • Fix chore reschedule issue cubewise-code/tm1py-samples#82

Compatibility Notes

  • requires Python 3.7 or higher
  • execute_mdx_values now returns a list object instead of a generator
  • the MDXUtils module has been removed. Use mdxpy instead
  • write_values now returns the changeset_id instead of a response object

Acknowledgments

Big thanks to @rkvinoth, @scrambldchannel, @andreyea, @adscheevel, @rclapp, @wimgielis for contributing code to this release, and many others for reporting bugs and requesting features.

How to upgrade TM1py

To upgrade TM1py, just use the following command:

pip install TM1py --upgrade