Changelog#
This is a detailed list of all changes. For a higher level view, see the Release notes.
Atoti Python SDK implements Atoti version policy in a specific manner to follow Semantic Versioning.
0.9.15#
Released on May 29, 2026.
Changed#
Upgraded Atoti Server to 6.1.20.
Upgraded Atoti UI and Atoti Admin UI to 5.2.24.
The Atoti UI app is served using its development build when
__debug__isTrue. It is strongly recommended to use Python’s optimized mode in production to avoid this development build’s overhead.Accept using the JDK that the
JAVA_HOMEenvironment variable points to even if its version is greater than 21.
Fixed#
data_model_transaction()raisingIllegalStateException: Structural transaction must be committed by the thread starting itdepending on the order of operations inside it [1].create_cube()from anexternal tablewithmode="no_measures"and afiltersending unfilteredAPPROX_COUNT_DISTINCTqueries forvirtual hierarchydetection [2].
Internal issue tracker references
0.9.14#
Released on April 17, 2026.
Added#
OpenTelemetry spans around the main functions and methods of the library. See
atoti_observabilityfor example traces.
Changed#
Upgraded Atoti Server to 6.1.19.
Deprecated#
atoti_directquery_databricks.ConnectionConfig.array_sum_agg_function_name,array_long_agg_function_name,array_short_agg_function_name, andarray_sum_product_agg_function_name. Spark UDAFs API has been deprecated as it is not recommended by Databricks anymore, usearray conversioninstead [4].
Fixed#
ModuleNotFoundErrorraised byatoti-clientwhenatoti-client-parquetis not installed.
Internal issue tracker references
PYTHON-798
PYTHON-817
0.9.13#
Released on March 10, 2026.
Added#
Documentation for
atoti-observability.Documentation for the ROLE_MEASURE_LINEAGE role in
atoti.security.Security.atoti_jdbc.JdbcPingDiscoveryProtocol.update_store_on_view_change[10].
Changed#
Upgraded Atoti Server to 6.1.18.
Upgraded Atoti UI and Atoti Admin UI to 5.2.20.
Renamed cloud storage packages:
atoti-client-aws→atoti-client-storage-awsatoti-server-aws→atoti-server-storage-awsatoti-client-azure→atoti-client-storage-azureatoti-server-azure→atoti-server-storage-azureatoti-client-gcp→atoti-client-storage-gcpatoti-server-gcp→atoti-server-storage-gcp
The module names have also changed:
atoti_aws→atoti_storage_awsatoti_azure→atoti_storage_azureatoti_gcp→atoti_storage_gcp
- uv add "atoti[aws]" + uv add "atoti[storage-aws]"
- from atoti_aws import ClientSideEncryptionConfig + from atoti_storage_aws import ClientSideEncryptionConfig
Deprecated#
atoti-client-aws,atoti-server-aws, and theatoti_awsmodule. Useatoti-client-storage-aws,atoti-server-storage-aws, andatoti_storage_awsinstead.atoti-client-azure,atoti-server-azure, and theatoti_azuremodule. Useatoti-client-storage-azure,atoti-server-storage-azure, andatoti_storage_azureinstead.atoti-client-gcp,atoti-server-gcp, and theatoti_gcpmodule. Useatoti-client-storage-gcp,atoti-server-storage-gcp, andatoti_storage_gcpinstead.
Fixed#
NotImplementedErrorraised when creating a==condition on a column operation [8], [9].atoti.Column.data_typeandatoti.Column.default_valueraising an error when accessed on aconnected sessionusing the"Object"data type [5].Setting MDX-related context values with
shared_contextnot being reflected in subsequent access toshared_contextin data cubes and raising an error in query cubes [7].
Internal issue tracker references
PIVOT-12311
PYTHON-703
PYTHON-768
PYTHON-774
PYTHON-775
PYTHON-789
0.9.12#
Released on January 23, 2026.
Added#
Changed#
Upgraded Atoti Server to 6.1.16.
Upgraded Atoti UI and Atoti Admin UI to 5.2.18.
Loading Apache Parquet files requires the new
atoti-client-parquetandatoti-server-parquetpackages [11].Installing the
atotipackage also installs these packages but the next breaking release will make them opt-in.- uv add "atoti" + uv add "atoti[parquet]"
If you do no use Parquet files and wish to reduce the size of your dependencies, you can skip the installation of the
atotipackage and manually install theatoti-clientandatoti-serverpackages instead:- # Also installs atoti-client-parquet and atoti-server-parquet. - uv add "atoti" + # Does not install atoti-client-parquet and atoti-server-parquet. + uv add "atoti-client" "atoti-server"
Or, if you use some extras:
- uv add "atoti[jdbc]" + uv add "atoti-client[jdbc]" "atoti-server[jdbc]"
Deprecated#
atoti.ParquetLoad[11]. Useatoti_parquet.ParquetLoadinstead:- from atoti import ParquetLoad + from atoti_parquet import ParquetLoad
read_parquet()since support for Apache Parquet will become opt-in [11]. Useinfer_data_types(),create_table(), andload()instead:- table = session.read_parquet(path, table_name="Example") + parquet_load = ParquetLoad(path) + data_types = session.tables.infer_data_types(parquet_load) + table = session.create_table("Example", data_types=data_types) + table.load(parquet_load)
atoti.Session.query_mdx()andatoti.Cube.query()’s timeout parameter [12].The default value has also been changed from
datetime.timedelta(seconds=30)toNoneto automatically useshared_context’squeriesTimeLimit.Use the context parameter to specify a custom timeout:
- session.query_mdx(mdx, timeout=datetime.timedelta(seconds=10)) + session.query_mdx(mdx, context={"queriesTimeLimit": 10})
- cube.query(m["contributors.COUNT"], timeout=datetime.timedelta(seconds=10)) + cube.query(m["contributors.COUNT"], context={"queriesTimeLimit": 10})
Fixed#
Atoti Admin UI connecting to wrong server due to wrong order of WebJars in the server’s classpath [14].
Hierarchies disappearing from the Data model tree when editing the data model of a
secured session[13].
Internal issue tracker references
PIVOT-12663
PYTHON-447
PYTHON-742
PYTHON-755
0.9.11#
Released on December 16, 2025.
Added#
pandas<3.0.0rc0upper bound to avoid breaking changes from the new str dtype [20].
Changed#
Upgraded Atoti Server to 6.1.15.
Upgraded Atoti UI and Atoti Admin UI to 5.2.17.
atoti.Measure.descriptionreturns""instead ofNone[18].Everything related to
Securityis kept in memory instead of being persisted in theuser_content_storage[15].This makes the API more consistent since all the other methods on
atoti.Sessionand its related classes never persisted their changes either. This improves performance, both when configuring these properties but also when executing queries.Note
Basic authentication credentialsare unaffected since, for security reasons, they were already only kept in memory.
Deprecated#
atoti.Measure.description’s deleter [18]. Set the description to a blank string instead:- del measure.description + measure.description = ""
Fixed#
Data model search bar display issue in JupyterLab extension [21].
Truncated response bodies when using
proxyorendpoint()[16].This operation is not supported while batching mutationserror raised when requesting anendpoint()[19].Users configured through
basic_authenticationunable to connect whenthe configured LDAP serveris unreachable [17].
Internal issue tracker references
PYTHON-716
PYTHON-717
PYTHON-728
PYTHON-733
PYTHON-737
PYTHON-739
PYTHON-745
0.9.10#
Released on October 31, 2025.
Added#
Support for Python 3.14 [23].
Dependencies page.
Changed#
Upgraded Atoti Server to 6.1.13.
Upgraded Atoti UI and Atoti Admin UI to 5.2.15.
Installation instructions with Conda to recommend Miniforge over Anaconda’s installer to not be tied to Anaconda’s license requirements [24].
Configuring
brandingdoes not remove the By ActiveViam signature at the bottom right corner of the app anymore. It is still possible to remove this signature through a customapp extension[22].
Internal issue tracker references
PYTHON-590
PYTHON-712
PYTHON-715
0.9.9.2#
Released on October 20, 2025.
Note
This version is not published on PyPI, it is only available on ActiveViam’s repository.
Added#
ROLE_ADMIN to
atoti.Hierarchy.viewers’s default value [26].
Changed#
Improved planning of MDX queries requesting many specific cells of the cube [25].
Reduce number of requests made when
representing(or evaluating in a Jupyter notebook cell) cubes, levels, measures, etc of aconnected session[27].
Fixed#
SSL: CERTIFICATE_VERIFY_FAILEDerror when requesting a customendpoint()on aSessionconfigured withhttps[28].
Internal issue tracker references
PIVOT-12464
PYTHON-697
PYTHON-698
PYTHON-705
0.9.9.1#
Released on September 30, 2025.
Note
This version is not published on PyPI, it is only available on ActiveViam’s repository.
Changed#
Improved planning of MDX queries requesting many specific cells of the cube [29].
Fixed#
ArrayIndexOutOfBoundsExceptionwhen running some MDX queries [30].AssertionError: Output has already been setwhen deleting a cube [32].GraphQLClientGraphQLMultiError: Structural transaction must be committed by the thread starting itwhen settingatoti.Measure.visibleinside adata_model_transaction()[31].
Internal issue tracker references
PIVOT-12032
PIVOT-12336
PYTHON-691
PYTHON-696
0.9.9#
Released on September 22, 2025.
Added#
Changed#
Upgraded Atoti Server to 6.1.12.
Upgraded Atoti UI and Atoti Admin UI to 5.2.13.
Improved the logic used in
atoti.Session.linkandatoti.Session.widgetto find the URL from which theSessioncan be reached from the JupyterLab extension [35].For instance, if Jupyter Server is running at https://1.9.9.1:8888 and the Atoti session is running on the same machine but on port 1337, the browser will try to reach the session from https://1.9.9.1:1337.
Fixed#
Incorrect
MdxQueryResultwhen disabling light crossjoin [37].Regression introduced in version 0.9.8 where
atoti.Session.endpointwould not handle URL encoded characters correctly [39].Inability to use Basic Authentication in requests made to
custom endpointswhen the session is secured withOIDC[40].
Internal issue tracker references
PIVOT-12095
PYTHON-592
PYTHON-621
PYTHON-629
PYTHON-632
PYTHON-634
PYTHON-677
PYTHON-678
0.9.8#
Released on August 12, 2025.
Added#
Changed#
Upgraded Atoti Server to 6.1.11.
When
atoti.JwtConfig.key_pairisNone, the automatically generated key pair will use 3072 bits instead of the old 2048 bits.
Deprecated#
Requests to endpoints created with
atoti.Session.endpointshould now use/proxyinstead of/atoti/pyapi./atoti/pyapiremains available but logs a warning when used [41].The
atoti.pyapimodule is deprecated, import its classes directly fromatoti.Useroratoti.endpoint.Requestinstead [41].
Fixed#
Performance regression when editing measures inside a
data_model_transaction()[42].
Internal issue tracker references
PYTHON-545
PYTHON-650
0.9.7#
Released on July 01, 2025.
Added#
atoti.finance.irr()’s period and guess parameters [49].
Changed#
Upgraded Atoti Server to 6.1.10.
Upgraded Atoti UI and Atoti Admin UI to 5.2.10.
atoti.AggregateProvider.measurescan be set toNoneto pre-aggregate all eligible measures [48].Measures can no longer be defined in a data
Cubeonce it joined a distribution cluster. The measures must be defined before settingatoti.Session.clusters, or the session must be started withatoti.SessionConfig.readyset toFalsewithatoti.Session.readyset toTrueonly once all measures have been defined [43].
Deprecated#
atoti.Hierarchy.visiblesetter [45]. Useatoti.Hierarchy.viewersinstead:- hierarchy.visible = False + hierarchy.viewers.clear() - hierarchy.visible = True + hierarchy.viewers.add("ROLE_USER")
Passing multiple levels of the same hierarchy to
atoti.AggregateProvider.levels. Only pass the deepest level instead:- tt.AggregateProvider(levels={l["Geography", "Country"], l["Geography", "City"]}) + tt.AggregateProvider(levels={l["Geography", "City"]})
Passing sequences to
atoti.AggregateProvider.levelsoratoti.AggregateProvider.measures. Pass sets instead:- tt.AggregateProvider(levels=[l["foo"]], measures=[m["bar"]]) + tt.AggregateProvider(levels={l["foo"]}, measures={m["bar"]})
Fixed#
where()rejecting condition if it contained a~hierarchy.isin(...)or~level.isin(...)leaf [47].atoti.finance.irr()returningnanwhen the actual rate was too large [49].
Internal issue tracker references
PIVOT-11612
PIVOT-11652
PYTHON-552
PYTHON-593
PYTHON-610
PYTHON-615
PYTHON-623
0.9.6#
Released on May 17, 2025.
Added#
allow_data_duplicationandatoti.Session.create_cube()’s priority parameter [51].unload_members_from_data_cube()andatoti.Session.create_cube()’s id_in_cluster parameter [50].Support for condition on hierarchy members (not only member paths) in
atoti.Cube.query()’s filter parameter [52].atoti.date_shift()’s dense parameter [56].experimental()context manager.
Changed#
Upgraded Atoti UI and Atoti Admin UI to 5.2.8.
Upgraded Atoti Server to 6.1.8.
The functions that were in the
atoti.experimentalsubpackage have been moved outside of it and require passing their feature key toexperimental():- tt.experimental.agg.distinct(...) + with tt.experimental({"agg.distinct"}): + tt.agg.distinct(...)
Deprecated#
Deleting a level through
atoti.Cube.levels. Redefine its hierarchy instead:- del l["Geography", "City"] + h["Geography"] = [l["Continent"], l["Country"]]
atoti.date_shift()’s method parameter [56]. The new parameter name is fallback:tt.date_shift( m["Price"], h["Date"], - method="previous", + fallback="past", offset="P1M", )
Fixed#
Display of join labels in
atoti.tables.Tables.schema[54].atoti.where()’s returned measure evaluating incorrectly when using|within another condition [53].Behavior of
get()when settingmapping_lookup()’s check toFalse.Missing continuous query updates when using measures such as
atoti.agg.sum()withCumulativeScope[55].
Internal issue tracker references
PYTHON-538
PYTHON-542
PYTHON-554
PYTHON-581
PYTHON-584
PYTHON-586
PYTHON-591
0.9.5#
Released on April 4, 2025.
Security#
SSO#
The atoti.KerberosConfig.username_case_conversion and atoti.LdapConfig.username_case_conversion attributes have been added to coerce the name of users logging in to the expected case [57].
Not picking a case conversion is a source of confusion or bugs so leaving these attributes unset will raise a deprecation warning.
Database access#
atoti.tables.Tables.owners and atoti.tables.Tables.readers have been added [58].
Their impact is not limited to the Python API.
For instance, atoti.tables.Tables.readers will also control whether end users are able to see tables in Atoti Admin UI Database tab.
Dependencies#
Fixed#
Data loading#
Cloud storage#
On Windows, passing a URL to atoti.CsvLoad.path or atoti_parquet.ParquetLoad.path raised an InvalidPathException [62].
Data modeling#
Conditions#
Creating logical conditions (i.e. boolean combinations of leaf conditions such as (level["Product"] == "Phone") | (level["Country"] == "Portugal")) with more than 508 leaves raised a ValidationError because it reached the maximum nesting depth supported by the runtime type checker [63].
This was fixed by allowing the internal representation of a logical condition to group more than 2 operands.
For example, (a & b) | c | d | f | g (with a maximum depth of 2) replaces the old internal representation (((a & b) | c) | (d | f)) | g (with a maximum depth of 4).
Table columns#
Columns are strictly typed: a column with a "LocalDate" data_type can only store dates (or None if its default_value is None); it cannot store a "String" such as "NaN".
Since Java has no equivalent of pandas.NaT, the only available values to represent a special null-restricted:
"LocalDate"areLocalDate.MINandLocalDate.MAX,"LocalDateTime"areLocalDateTime.MINandLocalDateTime.MAX.
However, accessing default_value when it was set to one of these values raised a ValidationError [59].
This is fixed.
Measures#
The type annotation of
filter()’s filter parameter never allowed invertedatoti.Level.isin()conditions (e.g.~level.isin("foo", "bar")) but, by chance, these conditions actually behaved as expected at runtime.However, 0.9.4 introduced runtime validation of condition types which lead to the rejection of these conditions. This regression is fixed: the type annotation of filter accepts these conditions and they are supported at runtime [60].
Passing
isnullconditions toatoti.where()raised anUnknownUnderlyingMeasureRuntimeException[61].
Internal issue tracker references
PIVOT-11110
PYTHON-528
PYTHON-529
PYTHON-534
PYTHON-536
PYTHON-539
PYTHON-548
0.9.4#
Released on February 28, 2025.
Distribution#
The name QuerySession, unused since 0.9.0, makes a come back in this release but, this time, with a different meaning.
QuerySession becomes the entry point to create clusters of Atoti applications [69].
atoti.Cube.restrictions has been introduced to secure query sessions.
For the sake of symmetry, atoti.Session.security.restrictions has moved to atoti.tables.Tables.restrictions (the old location remains available but is deprecated).
Performance#
Client/server communication#
Most components of Session are exposed through mappings such as Cubes or Tables.
As a project grows, a lot of mapping lookups will be made to iteratively define the data model or to pass arguments to methods such as atoti.Cube.query().
For instance, the following code will make 3 lookups:
new_measure = tt.agg.sum(
m["Foo.SUM"], # 1
scope=tt.OriginScope({
l["Bar"], # 2
l["Baz"], # 3
})
)
Each lookup makes a request to the server to check that the key exists.
This is pretty quick but, when thousands of lookups are made, this client/server communication can add up.
mapping_lookup() allows skipping these server requests.
Cube queries#
The aggregate cache of a cube can be restricted to a subset of measures [66].
This improvement comes with a new atoti.Cube.aggregate_cache API deprecating the previous atoti.Cube.aggregates_cache (with an “s”) one:
- cube.aggregates_cache.capacity = 200
+ cube.aggregate_cache = tt.AggregateCache(capacity=200)
- cube.aggregates_cache.capacity = -1
+ del cube.aggregate_cache
Hierarchy creation#
Creating hierarchies from columns of a table fully joined (i.e. all their keys are mapped) to the cube’s fact table do not require “rebuilding” the cube anymore [67]. This means that no time will be lost reindexing hierarchies or performing other expensive computations.
Data modeling#
Measures#
atoti.where() was not respecting the order of condition_to_value when the same value was assigned to multiple conditions [65].
For example, in:
m["8"] = 8
m["Test"] = tt.where(
{
m["8"] < 5: -1, # False
m["8"] >= 5: 1, # True
m["8"] < 10: -1, # True
},
default=0,
)
Test was equal to -1 because the first and last conditions, being both assigned to the same value, were merged together and that merged condition became the first one evaluating to True.
This incorrect merging of conditions has been removed: m["8"] >= 5 is correctly detected as the first condition evaluating to True and so Test is equal to 1.
Table columns#
Columns with an arrray data type can be made non-nullable.
atoti.Column.default_value’s documentation has been updated accordingly.
Data loading#
Transactions#
data_transaction()’s tables parameter allows some data transactions to execute concurrently [64].
CSV#
The atoti.CsvLoad.true_values and atoti.CsvLoad.false_values attributes can be configured to parse more values than "True", "true", "False", and "false" as "boolean" [68].
Dependencies#
Internal issue tracker references
PIVOT-10472
PIVOT-10571
PIVOT-10678
PIVOT-10995
PYTHON-190
PYTHON-296
0.9.3#
Released on January 13, 2025.
Added#
Changed#
Upgraded Atoti Server to 6.1.3.
Upgraded Atoti UI and Atoti Admin UI to 5.2.4.
SessionConfigand its inner classes validate that passedPathattributes exist. It prevents situations such as passing a path containing a typo toextra_jarsand being confused that the JAR’s classes still cannot be loaded.
Fixed#
read_parquet()andParquetLoadnot being able to load Parquet files with extension other than.parquet.NullPointerExceptionreturned by the server when executing some MDX queries.
0.9.2#
Released on December 05, 2024.
Added#
infer_data_types(),load(), andload_async()methods. Combined with the existingcreate_table()anddata_transaction()methods, they form the preferred way to create tables and load data into them.atoti_jdbc.JdbcLoad.parametersto bind variables to queries and avoid SQL injection.Runtime check that
atoti.OidcConfig.scopesincludes the required"openid"scope.
Documentation#
Pressing the y key after clicking on an anchor in a page under https://docs.activeviam.com/products/atoti/python-sdk/latest/ will permalink the URL by replacing latest with the corresponding version.
Changed#
Deprecated#
atoti.Table.append():- table.append(*rows) + table.load(pd.DataFrame(rows, columns=list(table)))
atoti.Table.load_arrow():- table.load_arrow(arrow_table) + table.load(arrow_table)
atoti.Table.load_csv():- table.load_csv(path) + table.load(tt.CsvLoad(path))
atoti.Table.load_kafka():- table.load_kafka(...) + from atoti_kafka import KafkaStream + table.stream(KafkaStream(...))
atoti.Table.load_numpy():- table.load_numpy(numpy_array) + table.load(pd.DataFrame(numpy_array, columns=list(table)))
atoti.Table.load_pandas():- table.load_pandas(pandas_df) + table.load(pandas_df)
atoti.Table.load_parquet():- table.load_parquet(path) + table.load(atoti_parquet.ParquetLoad(path))
atoti.Table.load_spark()- table.load_spark(spark_df) + table.load(spark_df.toPandas())
atoti.Table.load_sql():- table.load_sql(query, url=url) + from atoti_jdbc import JdbcLoad + table.load(JdbcLoad(query, url=url))
atoti.Session.read_numpy():- table = session.read_numpy(numpy_array, columns=columns) + table = session.read_pandas(pd.DataFrame(numpy_array, columns=columns))
atoti.Session.read_spark():- table = session.read_spark(spark_df) + table = session.read_pandas(spark_df.toPandas())
atoti.Session.read_sql():- table = session.read_sql(query, table_name=table_name, url=url) + from atoti_jdbc import JdbcLoad + jdbc_load = JdbcLoad(query, url=url) + data_types = session.tables.infer_data_types(jdbc_load) + table = session.create_table(table_name, data_types=data_types) + table.load(jdbc_load)
create_table(),read_arrow(),read_csv(),read_pandas(),read_parquet()’s types parameter. Use the data_types parameter instead.Inference of
read_csv()andread_parquet()’s table_name parameter. Pass a table_name argument instead.
Fixed#
RecursionErrorbeing raised when passing more than 296 cases towhere().KeyErrorbeing raised when using aLevelas a key inswitch()’s cases parameter.Snapshotting of
widgetin JupyterLab >= 4.2 by setting windowingMode to"defer".
0.9.1#
Released on October 18, 2024.
Added#
Support for Live extension to
atoti.Session.connect().
Changed#
Fixed#
Incorrect use of credentials when reading from S3 in
atoti-storage-aws.atoti.Cube.query()’s include_totals not including sub totals of multilevel slicing hierarchies.
0.9.0#
Released on September 13, 2024.
Added#
atoti-directquery-jdbcto connect to an external database through JDBC.data_model_transaction(). Batching measure creation with a data model transaction has the same performance as usingMeasures.update()without being limited to independent measures:- m.update({"foo": 13, "bar": 42}) - m.update({"foo + 1": m["foo"] + 1, "bar + 1": m["bar"] + 1}) + with session.data_model_transaction(): + m["foo"] = 13 + m["foo + 1"] = m["foo"] + 1 + m["bar"] = 42 + m["bar + 1"] = m["bar"] + 1
Data model transactions also replace the private API relying on
atoti.MeasureMetadata:- m["foo"] = (13, tt.MeasureMetadata(visible=True)) - m["bar"] = (42, tt.MeasureMetadata(description="The answer")) + with session.data_model_transaction(): + m["foo"] = 13 + m["foo"].visible = True + m["bar"] = 42 + m["bar"].description = "The answer"
atoti_directquery_redshift.ConnectionConfig.connection_pool_size.
User interface#
Filters tool in the sidebar of the JupyterLab extension to see default filters.
Changed#
Packaging#
The
atotipackage and most of its plugins (e.g.atoti-aws,atoti-directquery-directquery,atoti-kafkaetc.) have been split intoatoti-client-*andatoti-server-*packages. Theatoti-client-*packages contain the Python code composing the API while theatoti-server-*packages mostly contain the JARs implementing the corresponding features. The advanced installation section explains the goal of this split.The
atotipackage still exists but has become empty, it is only there to provide a convenient way to install both client and server packages. For instance:pip install atotiwill install bothatoti-clientandatoti-server. It will actually also installjdk4py.Note:
jdk4pyis not a dependency ofatoti-serverso that projects willing to use another JDK can avoid installingjdk4pyby dependending onatoti-clientandatoti-serverdirectly.pip install "atoti[aws]"will installatoti-client,atoti-aws-client,atoti-aws-server, andatoti-server.pip install "atoti[jupyterlab]"will installatoti-client,atoti-server, andatoti-jupyterlab(no client/server split for this package because it only contains frontend assets).
Because Conda does not support “extras”, the installation of Atoti plugins with this package manager is more complex. For instance, the command to install
atotiand its AWS plugin is:conda install atoti atoti-client-aws atoti-server-aws.
Session start and configuration#
atoti.Session.__init__()has been replaced withatoti.Session.start()for symmetry withatoti.Session.connect()(the removed section gives more details about that latter method):- session = tt.Session() + session = tt.Session.start()
The top-level config parameters have been grouped into a
SessionConfigdataclass providing better error reporting and allowing code reuse:- session = tt.Session(port=1337) + session = tt.Session.start(tt.SessionConfig(port=1337))
atoti.Session.__init__()’s authentication parameter has been replaced withatoti.SessionConfig.security:config = tt.OidcConfig(...) - tt.Session(authentication=config) + tt.Session.start(tt.SessionConfig(security=tt.SecurityConfig(sso=config)))
atoti.UserContentStorageConfighas been moved toatoti_jdbc.UserContentStorageConfig:- config = tt.UserContentStorageConfig(url=url) - tt.Session(user_content_storage=config) + from atoti_jdbc import UserContentStorageConfig + config = UserContentStorageConfig(url) + tt.Session.start(tt.SessionConfig(user_content_storage=config))
It makes it obvious that storing user content in an external database requires
atoti-jdbcto be installed.
DirectQuery#
DirectQuery
*ConnectionInfoand*TableOptionsclasses have been renamedConnectionConfigandTableConfig.- from atoti_directquery_clickhouse import ClickhouseConnectionInfo + from atoti_directquery_clickhouse import ConnectionConfig
- from atoti_directquery_clickhouse import ClickhouseTableOptions + from atoti_directquery_clickhouse import TableConfig
The
cacheattribute controlling whether DirectQuery connections should use caching has been moved from the connection instance to the connection config:- from atoti_directquery_snowflake import SnowflakeConnectionInfo + from atoti_directquery_snowflake import ConnectionConfig - connection_config = SnowflakeConnectionInfo(url=...) + connection_config = ConnectionConfig(url=..., cache=True) external_database = session.connect_to_external_database(connection_config) - external_database.cache = True
The
DatabricksConnectionInfo.heavy_load_urlattribute has been renamedfeeding_url.
Other#
Upgraded
jdk4pydependency to 21.0.4 which adds support for Linux Arm64.atoti_aws.AwsKeyPair,atoti_aws.AwsKmsConfig, andatoti_azure.AzureKeyPairhave been renamedKeyPair,KmsConfig, andKeyPair.The
atoti-sqlpackage has been renamedatoti-jdbc.atoti.Session.explain_mdx_query()andatoti.Cube.explain_query()have been replaced with an explain parameter toatoti.Session.query_mdx()andatoti.Cube.query():- session.explain_mdx_query(mdx) + session.query_mdx(mdx, explain=True)
atoti.Table.keysreturns atupleinstead of alist. It communicates that keys cannot be changed once the table exists.create_cube()’s base_table parameter has been renamed fact_table.
User interface#
Upgraded Atoti UI and Admin UI to 5.2.0.
Deprecated#
atoti.Session.port. Useatoti.Session.urlinstead:- url = f"http://localhost:{session.port}" + url = session.url
- port = session.port + from urllib.parse import urlparse + port = urlparse(session.url).port
atoti.Session.start_transaction(). Useatoti.tables.Tables.data_transaction()instead:- with session.start_transaction(): ... + with session.tables.data_model_transaction(): ...
atoti.Session.security.basic. Usebasic_authentication:- session.security.basic.credentials + session.security.basic_authentication.credentials
atoti.Table.columnsandatoti.ExternalTable.columns. Uselist(table)to list column names andfor column_name in table: ...to iterate on column names:- column_names = table.columns + column_names = list(table)
atoti.Hierarchy.levels. Iterate on theHierarchyinstead:- level_names = list(h["Geography"].levels) + level_names = list(h["Geography"])
- h["Date parts"] = {**h["Date parts"].levels, "Date": table["Date"]} + h["Date parts"] = {**h["Date parts"], "Date": table["Date"]}
Removed#
Support for Java 17, 18, 19, and 20.
The
atoti-querypackage and itsQuerySessionclass. Useatoti.Session.connect()instead:- pip install atoti-query + pip install atoti-client
- from atoti_query import QuerySession + from atoti as tt - existing_session = QuerySession(url) + existing_session = tt.Session.connect(url) existing_session.query_mdx(...)
atoti.Table.__len__(). It was ambiguous because it could be interpreted as counting either rows or columns. Instead, useatoti.Table.row_countto count rows andlen(list(table))to count columns:- row_count = len(table) + row_count = table.row_count
Previously deprecated#
Support for Python 3.9.
Support for pandas 1.
Support for JupyterLab 3.
atoti.UserServiceClient.atoti.Cube.schema.Support for passing an
inttoatoti.Table.load_kafka()’s batch_duration parameter.Variadic constructor of
OriginScope.Support for calling
atoti.Session.link().atoti.Session.visualize()andatoti.QuerySession.visualize().Support for passing a
Setto:atoti.Session()’s extra_jars or java_options parametersatoti.Cube.query()’s levels parameteratoti.Cube.create_parameter_simulation()’s levels parameteratoti.Cube.create_parameter_hierarchy_from_members()’s members parameter
Support for passing a
Sequenceto:DirectQuery
TableConfigclasses’ clustering_columns attribute
atoti.Session.security.users.atoti.Session.security.basic.usersandatoti.Session.security.basic.create_user().atoti.Session.security.rolesandatoti.Session.security.create_role().In-place mutation of
atoti.Security.security.ldap.role_mappingandatoti.Security.security.oidc.role_mapping’s values.In-place mutation of
atoti.Security.security.individual_roles’ values.