### Install Atoti Client Only using uv Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/getting_started/installation Installs only the 'atoti-client' package using 'uv'. This is suitable for projects that only need to connect to existing Atoti sessions and do not require starting new ones. ```shell uv add atoti-client ``` -------------------------------- ### Install Multiple Atoti Plugins using uv Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/getting_started/plugins Installs multiple Atoti plugins simultaneously using the 'uv' package manager. This example installs the 'directquery-jdbc', 'jupyterlab', and 'spring-boot-admin' extras. ```bash uv add "atoti[directquery-jdbc,jupyterlab,spring-boot-admin]" ``` -------------------------------- ### Install Atoti Server and Client with Custom JDK using uv Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/getting_started/installation Installs 'atoti-client' and 'atoti-server' using 'uv', skipping the default JDK installation. This method requires the JAVA_HOME environment variable to be set to a JDK version >= 21. ```shell uv add atoti-client atoti-server ``` -------------------------------- ### Install Atoti Client with JupyterLab Extension using uv Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/getting_started/installation Installs the 'atoti-client' package along with the JupyterLab extension using 'uv'. This option is for users who need the client and the extension but not the full Atoti package. ```shell uv add "atoti-client[jupyterlab]" ``` -------------------------------- ### Install Atoti with JupyterLab Extension using uv Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/getting_started/installation Installs the Atoti Python package along with the JupyterLab extension using the 'uv' package manager. This is the recommended method for most users. ```shell uv add "atoti[jupyterlab]" ``` -------------------------------- ### Test Atoti License Setup Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/guides/unlocking_all_features This script verifies if the ATOTI_LICENSE environment variable is set and if the Atoti license is valid. It checks for the presence of the environment variable and then attempts to start an Atoti session. If the variable is not found, it prompts the user to restart the Python process. It requires the 'os' and 'atoti' modules. ```python import os import atoti as tt assert "ATOTI_LICENSE" in os.environ, ( "Atoti license key not found, try restarting the Python process" ) session = tt.Session.start() ``` -------------------------------- ### Install Atoti with JupyterLab Extension using pip Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/getting_started/installation Installs the Atoti Python package along with the JupyterLab extension using 'pip'. This is an alternative to using 'uv' for package management. ```shell pip install "atoti[jupyterlab]" ``` -------------------------------- ### Initialize Atoti Session Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/guides/using_directquery Starts a new Atoti session, which is the primary entry point for interacting with the Atoti library. This session object will be used for all subsequent operations. ```python import atoti as tt session = tt.Session.start() ``` -------------------------------- ### Start Atoti Session Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/getting_started/tutorial/tutorial Initializes a new Atoti session. This is the first step in using the Atoti Python SDK to create data cubes and perform analysis. ```python import atoti as tt session = tt.Session.start() ``` -------------------------------- ### Start New Atoti Session Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti.Session.start Starts a new Atoti server subprocess and establishes a connection to it. It handles Java environment configurations, falling back to a default JVM if necessary. ```APIDOC ## POST /session/start ### Description Starts a new Atoti server subprocess and connects to it. If the JAVA_HOME environment variable is not defined or points to an unsupported Java version, the JVM from jdk4py will be used. ### Method POST ### Endpoint /session/start ### Parameters #### Query Parameters - **config** (SessionConfig | None) - Optional - The configuration for the session. #### Request Body - **kwargs** (Unpack[StartPrivateParameters]) - Optional - Additional parameters for starting the session. ### Response #### Success Response (200) - **Self** (object) - An object representing the active Atoti session. #### Response Example { "session_id": "a1b2c3d4-e5f6-7890-1234-567890abcdef" } ``` -------------------------------- ### Initializing and Connecting to an atoti Session with Security in Python Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti.tables.Tables.restrictions Provides the setup code for an atoti session, including security configurations and user authentication. This is a prerequisite for applying and testing data restrictions, as it establishes the environment and user sessions needed for the subsequent restriction examples. ```python session_config = tt.SessionConfig(security=tt.SecurityConfig()) session = tt.Session.start(session_config) # ... (data loading and cube creation) ... password = "abcdef123456" session.security.individual_roles["Rose"] = {"ROLE_USER"} session.security.basic_authentication.credentials["Rose"] = password rose_session = tt.Session.connect( session.url, authentication=tt.BasicAuthentication("Rose", password), ) session.security.individual_roles["Lena"] = { "ROLE_GERMANY", "ROLE_USER", } session.security.basic_authentication.credentials["Lena"] = password lena_session = tt.Session.connect( session.url, authentication=tt.BasicAuthentication("Lena", password), ) ``` -------------------------------- ### Set JVM Heap Size Limits Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/getting_started/deployment/deployment_setup This example shows how to configure the Java Virtual Machine (JVM) heap memory for an Atoti session. It includes setting the maximum heap size (`-Xmx`) and the initial heap size (`-Xms`). These parameters are essential for managing application memory usage in production. ```python import atoti session = atoti.Session(java_options=[ "-Xmx4g", # Maximum heap size of 4GB "-Xms1g" # Initial heap size of 1GB ]) ``` -------------------------------- ### Install Atoti DirectQuery JDBC Plugin using uv Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/getting_started/plugins Installs the DirectQuery JDBC plugin for Atoti using the 'uv' package manager. This command adds the 'directquery-jdbc' extra to the Atoti installation. ```bash uv add "atoti[directquery-jdbc]" ``` -------------------------------- ### Table Keys: No Keys Example (Python) Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti.Table.keys Demonstrates the behavior of a table without defined keys. Rows with identical values are treated as distinct entries, leading to duplicates. This example uses the `session.create_table` method and shows how to drop rows based on conditions. ```python >>> table = session.create_table( ... "No keys", data_types={"Product": "String", "Quantity": "int"} ... ) >>> table.keys () >>> table += ("Book", 42) >>> table += ("Book", 42) >>> table.row_count 2 >>> table.head().sort_index() Product Quantity 0 Book 42 1 Book 42 >>> table.drop((table["Product"] == "Book") & (table["Quantity"] == 42)) >>> table.row_count 0 ``` -------------------------------- ### Partitioned Cumulative Sum with atoti.CumulativeScope Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti.scope.cumulative_scope Shows how to use the 'partitioning' argument in atoti.CumulativeScope to perform cumulative aggregations within specific partitions. This example partitions the cumulative sum by month. ```python >>> m["Partitioned by month"] = tt.agg.sum( ... m["Quantity.SUM"], ... scope=tt.CumulativeScope(l["Day"], partitioning=l["Month"]), ... ) >>> cube.query( ... m["Quantity.SUM"], ... m["Partitioned by month"], ... levels=[l["Day"]], ... include_totals=True, ... ) ``` -------------------------------- ### Start Local HTTP Server in Python Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti.proxy This snippet demonstrates how to start a local HTTP server using Python's `ThreadingHTTPServer`. It binds to a random available port (0) and runs the server in a separate daemon thread, allowing the main program to continue execution. This is typically used as a proxy target. ```python from http.server import ThreadingHTTPServer from threading import Thread # Assuming RequestHandler is defined elsewhere and handles HTTP requests # For example: # class RequestHandler(BaseHTTPRequestHandler): # def do_GET(self): # self.send_response(200) # self.end_headers() # self.wfile.write(b"Hello, world!") local_server = ThreadingHTTPServer(("localhost", 0), RequestHandler) thread = Thread(daemon=True, target=local_server.serve_forever) thread.start() ``` -------------------------------- ### Create atoti Table Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti.Table.load Example of creating an atoti table with specified data types and keys. This is a prerequisite for loading data into the table. ```python >>> from datetime import date >>> table = session.create_table( ... "Sales", ... data_types={ ... "ID": "String", ... "Product": "String", ... "Price": "int", ... "Quantity": "int", ... "Date": "LocalDate", ... }, ... keys={"ID"}, ... ) ``` -------------------------------- ### Create and Configure AggregateProvider in Python Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti.aggregate_provider.aggregate_provider Demonstrates how to create an AggregateProvider for a given table and cube. It shows setting a filter, key, specific levels, and measures for pre-aggregation. The example uses pandas DataFrame and atoti session to build the cube and then configure the aggregate provider. ```python >>> df = pd.DataFrame( ... { ... "Seller": ["Seller_1", "Seller_1", "Seller_2", "Seller_2"], ... "ProductId": ["aBk3", "ceJ4", "aBk3", "ceJ4"], ... "Price": [2.5, 49.99, 3.0, 54.99], ... } ... ) >>> table = session.read_pandas(df, table_name="Seller") >>> cube = session.create_cube(table) >>> l, m = cube.levels, cube.measures >>> cube.aggregate_providers["Seller"] = tt.AggregateProvider( ... filter=l["Seller"] == "Seller_1", ... key="bitmap", ... levels={l["Seller"]}, ... measures={m["Price.SUM"]}, ... partitioning="modulo4(Seller)", ... ) >>> cube.aggregate_providers {'Seller': AggregateProvider(filter=l['Seller', 'Seller', 'Seller'] == 'Seller_1', key='bitmap', levels=frozenset({l['Seller', 'Seller', 'Seller']}), measures=frozenset({m['Price.SUM']}), partitioning='modulo4(Seller)')} ``` -------------------------------- ### Install Atoti and JupyterLab Extension using Conda Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/getting_started/installation Installs the Atoti package and its JupyterLab extension within the active Conda environment. This assumes the Atoti channel has already been added. ```shell conda install atoti atoti-jupyterlab ``` -------------------------------- ### Query Margin and Margin Rate by Product Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/getting_started/tutorial/tutorial Queries the cube to display the calculated Margin and Margin rate, grouped by Product level. This allows for analysis of product profitability. ```python cube.query(m["Margin"], m["Margin rate"], levels=[l["Product"]]) ``` -------------------------------- ### Copy Atoti Tutorial Notebook Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/getting_started/tutorial/tutorial Copies the tutorial notebook to the local file system for use in JupyterLab. This command-line utility is part of the Atoti Python SDK. ```bash python -m atoti.copy_tutorial tutorial ``` -------------------------------- ### Configure Conda Channel for Atoti Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/getting_started/installation Adds the ActiveViam Conda channel to the Conda configuration. This allows you to install Atoti packages using Conda. ```shell conda config --add channels https://activeviam.jfrog.io/artifactory/api/conda/conda ``` -------------------------------- ### Adding and Connecting as a New User in atoti (Python) Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti.Session.user Shows how to add a new user with specific roles and credentials to a secured `atoti` session, and then how to connect as this new user to access their specific permissions. ```python >>> username, password = "Cooper", "abcdef123456" >>> secured_session.security.individual_roles[username] = { ... "ROLE_PILOT", ... "ROLE_USER", ... } >>> secured_session.security.basic_authentication.credentials[username] = ( ... password ... ) ``` ```python >>> cooper_session = tt.Session.connect( ... secured_session.url, ... authentication=tt.BasicAuthentication(username, password), ... ) >>> cooper = cooper_session.user >>> cooper.name 'Cooper' >>> sorted(cooper.roles) ['ROLE_PILOT', 'ROLE_USER'] ``` -------------------------------- ### Activate Conda Environment Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/getting_started/installation Activates the previously created Conda environment named 'atoti'. All subsequent commands will run within this environment. ```shell conda activate atoti ``` -------------------------------- ### Create Conda Environment for Atoti Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/getting_started/installation Creates a new Conda environment named 'atoti'. This isolates Atoti and its dependencies from other Python projects. ```shell conda create --name atoti ``` -------------------------------- ### Initialize BigQuery ConnectionConfig Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti_directquery_bigquery.connection_config Demonstrates how to create an instance of ConnectionConfig to establish a connection to a BigQuery database. This is a prerequisite for using atoti's direct query capabilities with BigQuery. ```python from atoti_directquery_bigquery import ConnectionConfig connection_config = ConnectionConfig() ``` -------------------------------- ### Create Table with Data Types and Keys in Python Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti.Session.create_table This snippet demonstrates how to create an empty table named 'Product' using `session.create_table()`. It specifies the column names and their data types ('LocalDate', 'String', 'double'), and defines 'Product' and 'Date' as the table's keys. The example also shows how to retrieve the table's head, its column data types, and its keys. ```python >>> from datetime import date >>> table = session.create_table( ... "Product", ... data_types={ ... "Date": "LocalDate", ... "Product": "String", ... "Quantity": "double", ... }, ... keys={"Product", "Date"}, ... ) >>> table.head() Empty DataFrame Columns: [Quantity] Index: [] >>> {column_name: table[column_name].data_type for column_name in table} {'Date': 'LocalDate', 'Product': 'String', 'Quantity': 'double'} >>> table.keys ('Date', 'Product') ``` -------------------------------- ### Connect to atoti Session with Basic Authentication Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti.Session.connect Demonstrates how to connect to an existing atoti session using basic authentication. This example shows creating a session, configuring security, and then connecting to it as an administrator. It also illustrates modifying data through the connected session. ```python >>> session_config = tt.SessionConfig(security=tt.SecurityConfig()) >>> target_session = tt.Session.start(session_config) >>> _ = target_session.create_table("Example", data_types={"Id": "String"}) >>> target_session.security.individual_roles.update( ... {"user": {"ROLE_USER"}, "admin": {"ROLE_USER", "ROLE_ADMIN"}}, ... ) >>> password = "passwd" >>> target_session.security.basic_authentication.credentials.update( ... {"user": password, "admin": password} ... ) >>> admin_session = tt.Session.connect( ... target_session.url, ... authentication=tt.BasicAuthentication("admin", password), ... ) >>> table = admin_session.tables["Example"] >>> table += ("foo",) >>> table.head() Id 0 foo ``` -------------------------------- ### Get Row Count of an atoti Table Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti.Table.row_count This example demonstrates how to create an atoti table and retrieve its row count. It shows the initial count (0) and the count after adding a row. ```python >>> table = session.create_table( ... "Example", ... data_types={"Product": "String", "Quantity": "int"}, ... ) >>> table.row_count 0 >>> table += ("Book", 3) >>> table.row_count 1 ``` -------------------------------- ### Query Cube Data Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/guides/using_directquery Executes a query against the Atoti cube to retrieve aggregated data. This example fetches the 'Max Price' measure, grouped by the 'SHOP' level. ```python cube.query(m["Max Price"], levels=[l["SHOP"]]) ``` -------------------------------- ### Control Session Readiness with atoti.Session.ready (Python) Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti.Session.ready Demonstrates how to use the `session.ready` property to control access to an atoti session. It shows how to start a session with `ready=False`, configure user roles and authentication, and then test access for admin and regular users. Finally, it illustrates how changing `session.ready` to `True` and back to `False` affects user access. ```python import tt import httpx # Example usage of atoti.Session.ready admin_auth = "admin", "passwd" user_auth = "user", "passwd" session_config = tt.SessionConfig( ready=False, security=tt.SecurityConfig() ) session = tt.Session.start(session_config) print(f"Initial session ready state: {session.ready}") # Configure security for (username, password), roles in { admin_auth: {"ROLE_ADMIN"}, user_auth: {"ROLE_USER"}, }.items(): session.security.individual_roles[username] = roles session.security.basic_authentication.credentials[username] = ( password ) # Construct ping URL ping_path = f"{session.client.get_path_and_version_id('activeviam/pivot')[0]}/ping" url = f"{session.url}/{ping_path}" # Test access when session is not ready print("Testing access when session is not ready:") admin_response_not_ready = httpx.get(url, auth=admin_auth) user_response_not_ready = httpx.get(url, auth=user_auth) print(f"Admin access status: {admin_response_not_ready.status_code}") print(f"User access status: {user_response_not_ready.status_code}") # Make the session available to all users session.ready = True print(f"Session ready state after setting to True: {session.ready}") # Test access when session is ready print("Testing access when session is ready:") admin_response_ready = httpx.get(url, auth=admin_auth) user_response_ready = httpx.get(url, auth=user_auth) print(f"Admin access status: {admin_response_ready.status_code}") print(f"User access status: {user_response_ready.status_code}") # Make the session unavailable to non-admins again session.ready = False print(f"Session ready state after setting back to False: {session.ready}") # Test access when session is not ready again print("Testing access when session is not ready again:") admin_response_not_ready_again = httpx.get(url, auth=admin_auth) user_response_not_ready_again = httpx.get(url, auth=user_auth) print(f"Admin access status: {admin_response_not_ready_again.status_code}") print(f"User access status: {user_response_not_ready_again.status_code}") ``` -------------------------------- ### Initializing Pandas DataFrame Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/getting_started/tutorial/tutorial Demonstrates how to read a CSV file into a pandas DataFrame and display its head. This is a common first step when preparing data for Atoti simulations. ```python import pandas as pd products_df = pd.read_csv("data/products.csv") products_df.head() ``` -------------------------------- ### TableConfig Initialization with Array Conversion, Clustering, and Keys Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti_directquery_jdbc.table_config Demonstrates how to initialize the TableConfig class with options for array conversion, clustering columns, and table keys. This is useful for optimizing data loading and defining table structure. ```python from typing import AbstractSet, FrozenSet, Union, Optional # Assuming necessary imports for MultiColumnArrayConversion, MultiRowArrayConversion, etc. class TableConfig: def __init__(self, array_conversion: Optional[Union['MultiColumnArrayConversion', 'MultiRowArrayConversion']] = None, clustering_columns: AbstractSet[str] = frozenset({}), keys: Optional[Union[AbstractSet[str], FrozenSequence[str]]] = None): self.array_conversion = array_conversion self.clustering_columns = clustering_columns self.keys = keys # Example Usage: # config = TableConfig( # clustering_columns={'col1', 'col2'}, # keys={'id'} # ) ``` -------------------------------- ### Control Measure Visibility in atoti (Python) Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti.Measure.visible Demonstrates how to get and set the visibility of a measure using the `visible` property in atoti. This is useful for controlling which measures are displayed to users. The example uses pandas for data manipulation and the atoti Python SDK to create and interact with a cube. ```python import pandas as pd from py_client import Session session = Session("http://localhost:5050") df = pd.DataFrame( columns=["Product", "Price"], data=[ ("phone", 560), ("headset", 80), ("watch", 250), ], ) table = session.read_pandas(df, keys={"Product"}, table_name="Example") cube = session.create_cube(table) m = cube.measures # Get and set visibility print(m["Price.SUM"].visible) # Expected output: True m["Price.SUM"].visible = False print(m["Price.SUM"].visible) # Expected output: False print(m["contributors.COUNT"].visible) # Expected output: True m["contributors.COUNT"].visible = False print(m["contributors.COUNT"].visible) # Expected output: False ``` -------------------------------- ### Initialize Atoti Session and Load Data Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/guides/generating_pdf_reports Sets up an Atoti session and loads 'sales.csv' and 'products.csv' into tables. It defines the resources directory and joins the sales and products tables for cube creation. Dependencies include 'pathlib' and 'atoti'. ```python from pathlib import Path import atoti as tt resources_directory = Path().cwd().parent / "getting_started" / "tutorial" / "data" session = tt.Session.start() sales_table = session.read_csv( resources_directory / "sales.csv", keys={"Sale ID"}, table_name="Sales", ) products_table = session.read_csv( resources_directory / "products.csv", keys={"Product"}, table_name="Products", ) sales_table.join(products_table, sales_table["Product"] == products_table["Product"]) cube = session.create_cube(sales_table) l, m = cube.levels, cube.measures ``` -------------------------------- ### Make Proxy Request with Invalid Mode Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti.proxy This example demonstrates sending a GET request to the proxy endpoint with an unsupported `mode` parameter (`mode=invalid`). The server responds with a `400 Bad Request` status code, indicating that the provided mode is not recognized or handled. ```python import httpx response = httpx.get(f"{secured_session.url}/proxy/whoami?mode=invalid") print(response.status_code) ``` -------------------------------- ### Make Unauthenticated Proxy Request (JWT Mode) Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti.proxy This example demonstrates making an unauthenticated GET request to a proxied endpoint (`/proxy/whoami?mode=jwt`). It uses the `httpx` library to send the request and checks the response status code and JSON payload, which indicates an anonymous user. ```python import httpx response = httpx.get(f"{secured_session.url}/proxy/whoami?mode=jwt") print(response.status_code) print(response.json()) ``` -------------------------------- ### Initializing Atoti Session (Python) Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/changelog/0.9.0 Shows the updated method for starting an Atoti session, replacing `atoti.Session.__init__()` with `atoti.Session.start()`. This change promotes symmetry with `atoti.Session.connect()` and provides a more consistent API. ```python - session = tt.Session() + session = tt.Session.start() ``` -------------------------------- ### Set and Get Measure Description in Python Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti.Measure.description Demonstrates how to set and retrieve the description for a measure using the atoti Python SDK. This involves creating a pandas DataFrame, reading it into Atoti, creating a cube, and then manipulating the description property of a measure. The example shows setting a description, retrieving it, and also handling blank descriptions. ```python import pandas as pd from activepivot.api import Session session = Session() df = pd.DataFrame( columns=["Product", "Price"], data=[ ("phone", 560), ("headset", 80), ("watch", 250), ], ) table = session.read_pandas( df, keys={"Product"}, table_name="Example" ) cube = session.create_cube(table) m = cube.measures # Get initial description print(m["Price.SUM"].description) # Set a description m["Price.SUM"].description = "The sum of the price" # Get the updated description print(m["Price.SUM"].description) # Set a blank description m["Price.SUM"].description = " " # Get the blank description print(m["Price.SUM"].description) ``` -------------------------------- ### Configure Basic Authentication Credentials and Roles (Python) Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti.security.basic_authentication_security.BasicAuthenticationSecurity.credentials Demonstrates how to set up basic authentication by assigning roles to users and configuring their credentials. It also shows how to update passwords and the security measure of redacting retrieved passwords. ```python >>> session_config = tt.SessionConfig(security=tt.SecurityConfig()) >>> session = tt.Session.start(session_config) >>> session.security.basic_authentication.credentials {} >>> session.security.individual_roles["Chen"] = {"ROLE_USER"} >>> session.security.basic_authentication.credentials["Chen"] = "Peking" >>> session.security.basic_authentication.credentials["Chen"] = "Beijing" >>> session.security.basic_authentication.credentials {'Chen': '**REDACTED**'} >>> del session.security.basic_authentication.credentials["Chen"] >>> session.security.basic_authentication.credentials {} >>> del session.security.individual_roles["Chen"] ``` -------------------------------- ### Proxy Request on Session Without Security Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti.proxy This example illustrates making a proxy request (`/proxy/whoami?mode=session`) on an Atoti session that does not have security configured. The request succeeds with a `200 OK` status, and the response identifies an anonymous user with default roles, showing that `connect()` and `session.user` work even without explicit authentication setup. ```python import httpx # Assuming 'session' is an Atoti session object without security configured # and local_server is running session.proxy.url = f"http://localhost:{local_server.server_port}" response = httpx.get(f"{session.url}/proxy/whoami?mode=session") print(response.status_code) print(response.json()) ``` -------------------------------- ### Query Cube with Multiple Scenarios Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/getting_started/tutorial/tutorial This code queries the 'Quantity.SUM' measure using the 'Country Simulation' level. It displays the results for the 'Base' case, 'France Crisis' scenario, and the newly added 'US boost' scenario, showing how different parameter values impact the aggregated quantity. ```python cube.query(m["Quantity.SUM"], levels=[l["Country Simulation"], l["Country"]]) ``` -------------------------------- ### Instantiate KeyPair for Client-Side Encryption (Python) Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti_azure.client_side_encryption.key_pair Demonstrates how to create an instance of the KeyPair class for client-side encryption using atoti_azure. This requires providing the public key, private key, and optionally a key ID. ```python from atoti_azure import KeyPair client_side_encryption = KeyPair( "public_key", "private_key", key_id="key_id" ) ``` -------------------------------- ### Add User and Make Authenticated Proxy Request (JWT Mode) Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti.proxy This example shows how to add a user ('Alice') with specific roles (`ROLE_USER`, `ROLE_WONDERLAND`) and basic authentication credentials to the Atoti session. It then makes an authenticated GET request to the `/proxy/whoami?mode=jwt` endpoint using these credentials. The response correctly identifies 'Alice' and her assigned roles. ```python import httpx username, password = "Alice", "abcdef123456" alice_roles = {"ROLE_USER", "ROLE_WONDERLAND"} secured_session.security.individual_roles[username] = alice_roles secured_session.security.basic_authentication.credentials[username] = ( password ) response = httpx.get( f"{secured_session.url}/proxy/whoami?mode=jwt", auth=(username, password), ) print(response.status_code) print(response.json()) ``` -------------------------------- ### Instantiate KeyPair for Client-Side Encryption Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti_aws.client_side_encryption.key_pair Demonstrates how to create an instance of the KeyPair class for client-side encryption. This requires providing the public key, private key, and the AWS region. ```python from atoti_aws import KeyPair client_side_encryption = KeyPair( "public_key", "private_key", region="eu-west-3", ) ``` -------------------------------- ### Unload Members from Data Cube using Python Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti.QueryCube.unload_members_from_data_cube Demonstrates how to unload members from a data cube using the `unload_members_from_data_cube` method. This example sets up a query session, defines a query cube, creates a data cube, and then unloads specific members ('London', 'Madrid') from the 'City' level. It includes setup for the query and data sessions, data loading, and verification steps before and after unloading. ```python >>> from pathlib import Path >>> from secrets import token_urlsafe >>> from tempfile import mkdtemp >>> from time import sleep >>> import pandas as pd >>> from atoti_jdbc import JdbcPingDiscoveryProtocol >>> application_name = "Cities" >>> cluster_name = "Cluster" >>> data_cube_id = "Europe" >>> query_cube_name = "Query cube" # Setting up the `query cube`: >>> query_session = tt.QuerySession.start() >>> cluster_definition = tt.ClusterDefinition( ... application_names={application_name}, ... discovery_protocol=JdbcPingDiscoveryProtocol( ... f"jdbc:h2:{Path(mkdtemp('atoti-cluster')).as_posix()}/db", ... username="sa", ... password="", ... ), ... authentication_token=token_urlsafe(), ... ) >>> query_session.session.clusters[cluster_name] = cluster_definition >>> query_session.query_cubes[query_cube_name] = tt.QueryCubeDefinition( ... query_session.session.clusters[cluster_name], ... allow_data_duplication=True, ... distributing_levels={(application_name, "City", "City")}, ... ) # Defining some functions: >>> def query_by_city(): ... cube = query_session.session.cubes[query_cube_name] ... l, m = cube.levels, cube.measures ... return cube.query(m["Number.SUM"], levels=[l["City"]]) >>> def wait_for_data(*, expected_city_count: int): ... max_attempts = 30 ... for _ in range(max_attempts): ... try: ... result = query_by_city() ... if len(result.index) == expected_city_count: ... return ... except: ... pass ... sleep(1) ... raise RuntimeError(f"Failed {max_attempts} attempts.") # Setting up the `data cube`: >>> data_session = tt.Session.start() >>> data = pd.DataFrame( ... columns=["City", "Number"], ... data=[ ... ("Paris", 20.0), ... ("London", 5.0), ... ("Madrid", 7.0), ... ], ... ) >>> table = data_session.read_pandas( ... data, keys={"City"}, table_name=application_name ... ) >>> data_cube = data_session.create_cube(table, id_in_cluster=data_cube_id) # Waiting for the data cube to join the cluster: >>> data_session.clusters[cluster_name] = cluster_definition >>> wait_for_data(expected_city_count=3) >>> query_by_city() Number.SUM City London 5.00 Madrid 7.00 Paris 20.00 # Unloading the facts associated with the London and Madrid members: >>> query_session.query_cubes[ ... query_cube_name ... ].unload_members_from_data_cube( ... {"London", "Madrid"}, ... data_cube_id=data_cube_id, ... level=data_cube.levels["City"], ... ) >>> wait_for_data(expected_city_count=1) >>> query_by_city() Number.SUM City Paris 20.00 ``` -------------------------------- ### Install Atoti DirectQuery JDBC Plugin using pip Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/getting_started/plugins Installs the DirectQuery JDBC plugin for Atoti using the 'pip' package manager. This command adds the 'directquery-jdbc' extra to the Atoti installation. ```bash pip install "atoti[directquery-jdbc]" ``` -------------------------------- ### Querying Data with Measures and Levels in Atoti Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/getting_started/tutorial/tutorial Demonstrates how to query data from an Atoti cube, selecting specific measures and defining hierarchical levels for aggregation. This is useful for retrieving aggregated data for analysis. ```python cube.query(m["Percent of parent amount"], m["Margin rate"], levels=[l["Category"]]) ``` -------------------------------- ### Install Atoti DirectQuery JDBC Plugin using Conda Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/getting_started/plugins Installs the DirectQuery JDBC plugin for Atoti using the 'conda' package manager. This method installs separate packages for the client and server components. ```bash conda install atoti atoti-client-directquery-jdbc atoti-server-directquery-jdbc ``` -------------------------------- ### Examples of atoti.where() Conditions Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti.function.where Provides examples of various condition types supported by atoti.where(). These include comparing measures to values, levels to levels, levels to constants, and combining conditions using logical operators (& for AND, | for OR). These examples showcase the flexibility in defining conditional logic. ```python # Measures compared to anything measure-like: m["Test"] == 20 # Levels compared to levels, (if the level is not expressed, it is considered None): l["source"] == l["destination"] # Levels compared to constants of the same type: l["city"] == "Paris" l["date"] > datetime.date(2020, 1, 1) l["age"] <= 18 # A conjunction or disjunction of conditions using the `&` operator or `|` operator: (m["Test"] == 20) & (l["city"] == "Paris") (l["Country"] == "USA") | (l["Currency"] == "USD") ``` -------------------------------- ### atoti.Session.create_table() Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti.Session.create_table Creates an empty table with specified columns, data types, default values, keys, and partitioning. ```APIDOC ## POST /session/create_table ### Description Creates an empty table with columns of the given data types. This method allows for the specification of column data types, default values, key columns, and partitioning strategies. ### Method POST ### Endpoint /session/create_table ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **name** (str) - Required - The name of the table to create. - **data_types** (Mapping[str, str]) - Required - A mapping of column names to their corresponding data types (e.g., 'LocalDate', 'String', 'double'). - **default_values** (Mapping[str, Any]) - Optional - A mapping from column name to its default value or None. - **keys** (Set[str] | Sequence[str]) - Optional - The columns that will become the keys of the table. If a Set is given, the keys will be ordered as the table columns. - **partitioning** (str | None) - Optional - The definition of how the data will be split across partitions. Default rules apply if not specified. Example: "modulo4(country)". - **kwargs** (Unpack[TablePrivateParameters]) - Optional - Additional private parameters for table creation. ### Request Example ```json { "name": "Product", "data_types": { "Date": "LocalDate", "Product": "String", "Quantity": "double" }, "keys": { "Product", "Date" } } ``` ### Response #### Success Response (200) - **Table** (object) - The newly created table object. #### Response Example ```json { "message": "Table 'Product' created successfully." } ``` ``` -------------------------------- ### Simulate New File Arrival and Observe Table Update Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/guides/watching_local_files This snippet simulates the arrival of a new sales data file by copying it into the watched directory. It then includes a loop that waits until the 'Sales' table's row count increases, indicating that the file watcher has detected and loaded the new file. Finally, it queries the cube to show that the new data is reflected. ```python from shutil import copy # Copy the new file ... copy( resources_directory / "next" / "sales_2021_05_03.csv", resources_directory / "current", ) # ... and briefly wait until we see that new rows have been added to the table while sales_table.row_count <= initial_row_count: pass # Query the cube to show the updated data cube.query(m["Quantity.SUM"], levels=[l["Date"]]) ``` -------------------------------- ### Install atoti-client instead of atoti-query Source: https://docs.activeviam.com/products/atoti/python-sdk/latest/changelog/0.9.0 This code snippet shows the change in package installation for Atoti query capabilities. `atoti-query` is no longer supported and should be replaced with `atoti-client`. ```bash - pip install atoti-query + pip install atoti-client ```