0.5.0 (2020-12-08)


  • Some functionalities have been moved to plugin packages to lighten the core atoti package.

  • 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 .gz, .tar.gz, or .zip archives 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.



The atoti.experimental module regroups new features that can go through breaking changes in minor and/or patch releases. Its initial content is:


  • 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.

  • BREAKING: Cube.visualize() has been replaced with session.Session.visualize() that requires the atoti-jupyterlab plugin. Widgets made with Cube.visualize() will have to be rebuilt with the new JupyterLab extension.

  • BREAKING: AWS S3 and Kafka loading are no longer supported in the base package, they require the plugins atoti-aws and atoti-kafka respectively.

  • BREAKING: Hierarchy are put in a dimension with the same name as the store which feeds their levels.

  • BREAKING: math functions have been moved to the atoti.math module: math.abs(), math.ceil(), math.cos(), math.exp(), math.floor(), math.log(), math.log10(), math.max(), math.min(), math.round(), math.sin(), math.sqrt() and math.tan().

  • BREAKING: parent_value()’s degree parameter has been replaced by a degrees mapping to support multiple hierarchies.

  • BREAKING: comparator.first_members()’s members parameter has been made variadic instead of accepting a collection.

  • BREAKING: atoti.types module and AtotiType class have been respectively renamed atoti.type and DataType. Array and nullable types have also been renamed for improved grammar and consistency.

  • BREAKING: session.Session.endpoint()’s method parameter has been made keyword-only.

  • BREAKING: level.Level.data_type’s type changed from str to DataType.

  • BREAKING: The constructors of the following classes are no longer part of the API and have been replaced by factory functions:

    • config.SessionConfigurationconfig.create_config()

    • config.BasicAuthenticationconfig.create_basic_authentication()

    • config.BasicUserconfig.create_basic_user()

    • config.OidcAuthenticationconfig.create_oidc_authentication()

    • query.basic_auth.BasicAuthenticationquery.create_basic_authentication()

  • BREAKING: cube.Cube.create_parameter_hierarchy() has been renamed cube.Cube.create_static_parameter_hierarchy.

  • 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.

  • BREAKING: 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 data and status keys.

  • 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.

  • session.Session.query_mdx() and 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 None in the resulting DataFrame instead of being converted to NaN.

  • ROLE_USER is 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 openjdk Conda package is no longer required.

  • The data loaded while a sampling mode is active is now consistent between store and cube manipulations.


  • BREAKING: agg.stop() moved to agg._stop() as its behavior can be replicated with where():

    - m["Stopped price"] = tt.agg.stop(m["Price"], l["Product"], l["Shop"])
    + m["Stopped price"] = tt.where(
    +     (l["Product"] != None) & (l["Shop"] != None), m["Price"]
    + )
  • BREAKING: agg.single_value() moved to agg._single_value() as value() can be used for its main use-case: creating a measure based on the value of a store column.