Session configuration

When deploying a project, some additional configuration is available. As configuration can depend on where the project is deployed, the configuration can either be defined in YAML files or in Python code through the atoti.config package.

The configuration is passed as an argument of create_session, either as a path to the YAML file or directly as a Python object.

[1]:
import atoti as tt
Welcome to atoti 0.4.0!

By using this community edition, you agree with the license available at https://www.atoti.io/eula.
Browse the official documentation at https://docs.atoti.io.
Join the community at https://www.atoti.io/register.

You can hide this message by setting the ATOTI_HIDE_EULA_MESSAGE environment variable to True.

Port and URL

Port

The port used by the atoti server is random but can be set to a specific value:

[2]:
config = tt.config.create_config(port=8080)

or in a YAML file:

port: 8080

URL pattern

This sets the URL displayed by session.url to connect to the user interface. The {{host}} and {port} placeholders will be replaced with, respectively, the actual host address and port number. Defaults to http://localhost:{port}.

In a YAML file it can be set like that:

url_pattern: https://example.com:{port}/

equivalent to

[3]:
config = tt.config.create_config(url_pattern="https://example.com:{port}/")

Metadata database

Some data, such as the dashboards generated by the users, is not part of the data sources but is stored anyway in what we call the metadata database. By default, this database is in memory so everything is lost when the atoti session is closed. However, it can also be persisted to a file.

This is an example of configuration that stores the metadata in a file:

metadata_db: ./metadata.db

which is equivalent to the following Python code:

[4]:
config = tt.config.create_config(metadata_db="./metadata.db")

Security

Enterprise only: Security is only available in the Enterprise edition of the library.

When sharing your application with other users, you can set up security to configure which users are allowed to connect to the application and which part of the data they are allowed to see.

Roles

Roles are a way to restrict what users can see in a cube. By default, all users mentioned in your configuration file have a role called ROLE_USER which gives access to the full cube. You can define additional roles with restrictions and give these roles to your users.

This in an example of roles in a YAML file:

roles:
  - name: ROLE_FRANCE
    restrictions:
      Country: France
      Currency: Euro
  - name: ROLE_AMERICA
    restrictions:
      Country: [USA, Canada]
  - name: ROLE_CHINA
    restrictions:
      Country: [China]

Roles can also be defined directly in Python:

[5]:
from atoti.config import create_role

french = create_role(
    "ROLE_FRANCE", restrictions={"Country": "France", "Currency": "Euro"}
)
american = create_role("ROLE_AMERICA", restrictions={"Country": ["USA", "Canada"]})
chinese = create_role("ROLE_CHINA", restrictions={"Country": "China"})

config = tt.config.create_config(roles=[french, american, chinese])

Roles are defined per column. Column restrictions are inherited by all hierarchies based on this column. For instance, in the previous configuration, a user with the role ROLE_AMERICA will only see the data related to USA and Canada and won’t see the data for France.

Combining roles

Restrictions on different hierarchies are intersected. For instance, in the previous configuration, a user with the role ROLE_FRANCE will only see the data where the country is France AND the currency is Euro.

However, if a user has several roles with restrictions on the same hierarchies, the access to the union of restricted members will be granted. For instance, in the previous configuration, a user with both ROLE_AMERICA and ROLE_CHINA will see the data where the country is USA, Canada, OR China.

Authentication

Basic

Basic handles authentication with usernames and passwords. It is the easiest way to get started with security on a project, you only have to define the users, their password, and their roles.

This is an example of YAML configuration defining 3 users:

authentication:
  basic:
    users:
      - name: admin
        password: nidma
        roles:
          - ROLE_ADMIN
      - name: user1
        password: 1resu
        roles:
          - ROLE_FRANCE
      - name: user2
        password: 2resu
        roles:
          - ROLE_UK

Which is equivalent to the following Python code:

[6]:
from atoti.config import BasicAuthentication, BasicUser

admin = BasicUser("admin", "nidma", ["ROLE_ADMIN"])
user1 = BasicUser("user1", "1resu", ["ROLE_FRANCE"])
user2 = BasicUser("user2", "2resu", ["ROLE_UK"])
basic = BasicAuthentication([admin, user1, user2], realm="Configuration Tutorial")

config = tt.config.create_config(authentication=basic)

Auth0

Auth0 is an authentication and authorization platform, it can easily be connected to atoti to handle the authentication.

The configuration requires :

  • information about your application.

  • a role mapping which is a mapping between Auth0 users and atoti roles

This is an example of YAML configuration for Auth0 giving access to other users:

authentication:
  auth0:
    issuer: myIssuer
    audience: myAudience
    client_id: myClientId
    client_secret: myClientSecret
    role_mapping:
      admin:
        - ROLE_ADMIN
      french_user:
        - ROLE_FRANCE

which is equivalent to the following Python code:

[7]:
from atoti.config import Auth0Authentication

auth0 = Auth0Authentication(
    issuer="myIssuer",
    audience="myAudience",
    client_id="myClientId",
    client_secret="myClientSecret",
    role_mapping={"admin": ["ROLE_ADMIN"], "french_user": ["ROLE_FRANCE"]},
)

Sampling mode

Sets the default sampling mode for all the stores. When building the data model it is more efficient to work only on part of the data. Once the modeling is over, everything can be loaded by calling Session.load_all_data()

This mode will load only the first 10,000 lines for each store:

sampling:
  first_lines: 10000

This mode will load only the first file for each store:

sampling:
  first_files: 1

This mode will load all the data:

sampling: full

These can also be defined in Python:

[8]:
from atoti.sampling import FULL, first_lines, first_files

config = tt.config.create_config(sampling_mode=first_lines(10000))
config = tt.config.create_config(sampling_mode=first_files(1))
config = tt.config.create_config(sampling_mode=FULL)

Application memory

atoti loads all the data in memory. The max memory can be set to increase the capacity of the application.

The format is a string containing a number followed by a unit among G, M and K, for instance “64G”. This actually sets the -Xmx JVM parameters and defaults to the JVM default memory which is 25% of the machine memory.

max_memory: 64G
[9]:
config = tt.config.create_config(max_memory="64G")

Advanced Java Arguments

It is possible to provide additional arguments to Java in order to do some custom optimization or debugging

In YAML it is done with a list of arguments:

java_args:
  - "-Xms1g"
  - "-XX:+UseG1GC"

equivalent to this Python code:

[10]:
config = tt.config.create_config(java_args=["-Xms1g", "-XX:+UseG1GC"])

Configuration inheritance

Sometimes, you want to use the same base configuration for all your projects. For instance, if you are using the Auth0 account of your company, you won’t want to repeat its properties everywhere. To avoid that, a configuration file can inherit the default configuration file and be merged with it.

A default configuration file can be placed at $ATOTI_HOME/config.yml where $ATOTI_HOME defaults to $HOME/.atoti.

By default, the configuration will inherit the default one, if you don’t want this behaviour, add inherit: False to your configuration.

A classic example is to have a default config.yml with the Auth0 properties:

authentication:
  auth0:
    issuer: myIssuer
    audience: myAudience
    client_id: myClientId
    client_secret: myClientSecret

and have a configuration specific to each project with the role mapping:

authentication:
  auth0:
    roles:
      admin:
        - ROLE_ADMIN
      french_user:
        - ROLE_FRANCE

Environment variables

Environment variables can be used in the configuration with the following syntax:

authentication:
  basic:
    users:
      - name: ${{ env.PROJECT_USERNAME }}
        password: ${{ env.PROJECT_PASSWORD }}