Some functionalities have been moved to plugin packages to lighten the core
The web application and the JupyterLab extension have been rewritten from scratch to provide better performances and a simpler experience. atoti’s JupyterLab extension leverages JupyterLab 3’s federated extension system meaning that Node.js and the rebuilding of JupyterLab are not required anymore for its installation. It is also distributed as an atoti plugin instead of a separate npm or Conda package.
Data can be loaded from more sources: Amazon S3, Azure Blob Storage, Google Cloud Storage, and SQL databases. On the fly decompression of CSV files stored in
.ziparchives has also been added.
The name of the default dimension of a hierarchy has changed from Hierarchies to the name of the store on which the hierarchy is based.
Plugins bringing additional features:
atoti-azureto load CSV and parquet file from Azure Blob Storage.
atoti-gcpto load CSV and parquet file from Google Cloud Storage.
atoti-sqlto load results of SQL queries into atoti stores.
Support for path parameters in
endpoint()’s route parameter.
Hierarchy visibility can be toggled through the
Support for reading
.zipfiles containing compressed CSV(s) (#123).
value()to create a measure based on the value of a store column.
hierarchized_columns parameter to select which columns of a store are converted into hierarchies. It is available in these methods:
config.create_ldap_authentication()to setup LDAP authentication in Atoti+.
Support for multiple hierarchies in
Support for negative value in array indexing (#149).
cube.Cube.create_store_column_parameter_hierarchy()to create parameter hierarchies from existing store columns.
array.quantile_index()returning the index of the desired quantile.
Runtime type checking on all the public API functions.
branding, extra_jars, https, and same_site parameters to
atoti.experimental module regroups new features that can go through breaking changes in minor and/or patch releases.
Its initial content is:
atoti.experimental.distributedto create distributed clusters of atoti cubes.
atoti.experimental.finance.irr()to compute an internal rate of return.
atoti.experimental.statsproviding the probability distribution functions
ppffor Normal, Chi-square, Student’s t, Beta and F distributions.
BREAKING: The web application requires a new initial file structure in the metadata DB. Metadata DBs created in previous versions are not compatible with this version and will have to be recreated.
Cube.visualize()has been replaced with
session.Session.visualize()that requires the
atoti-jupyterlabplugin. Widgets made with
Cube.visualize()will have to be rebuilt with the new JupyterLab extension.
Hierarchyare put in a dimension with the same name as the store which feeds their levels.
BREAKING: math functions have been moved to the
parent_value()’s degree parameter has been replaced by a degrees mapping to support multiple hierarchies.
comparator.first_members()’s members parameter has been made variadic instead of accepting a collection.
session.Session.endpoint()’s method parameter has been made keyword-only.
BREAKING: The constructors of the following classes are no longer part of the API and have been replaced by factory functions:
cube.Cube.create_parameter_hierarchy()has been renamed
BREAKING: Store names inferred from file paths are capitalized.
BREAKING: Key columns cannot be nullable anymore and are automatically made non nullable. String and date columns are also inferred as non nullable.
config.create_config()’s inherit parameter has been renamed inherit_global_config.
BREAKING: JSON responses generated from
endpoint()are no longer encapsulated into an object with
BREAKING: .VALUE measures are no longer automatically created from numeric columns of joined stores.
The first MDX query run by an atoti widget in JupyterLab is no longer executed in Python. Instead, the query is executed client-side like before 0.4.3 and the call to
visualize()will block until this first query is done.
query.session.QuerySession.query_mdx()support any MDX SELECT query (more than 2 axes, measures on rows, or totals). Empty measure values will also be kept as
Nonein the resulting DataFrame instead of being converted to
ROLE_USERis no longer automatically added to the role mapping of
config.create_oidc_authentication()and must be given explicitly.
atoti’s Conda package depends on jdk4py so the installation of the
openjdkConda package is no longer required.
The data loaded while a sampling mode is active is now consistent between store and cube manipulations.
agg._stop()as its behavior can be replicated with
- m["Stopped price"] = tt.agg.stop(m["Price"], lvl["Product"], lvl["Shop"]) + m["Stopped price"] = tt.where( + (lvl["Product"] != None) & (lvl["Shop"] != None), m["Price"] + )
value()can be used for its main use-case: creating a measure based on the value of a store column.
HTML entities are correctly encoded in widget snapshots (#148).
Issue with boolean type in Parquet files (#157).
agg.count_distinct()support for measure and scope parameters.