Repository: dscc-admin-ch/lomas (language: python)

Issue:
add another improvement
and one more


Discussion / hints:

Fix patch:
diff --git a/client/documentation/client.rst b/client/documentation/client.rst
index 904d2da5..fbfd93d4 100644
--- a/client/documentation/client.rst
+++ b/client/documentation/client.rst
@@ -154,7 +154,6 @@ This function executes an OpenDP query.
     res = client.opendp_query(
         self,
         opendp_pipeline,
-        input_data_type: str = "df",
         dummy: bool = False,
         nb_rows: int = 100,
         seed: int = 42,
@@ -162,7 +161,6 @@ This function executes an OpenDP query.
 
 Parameters:
     - `opendp_pipeline`: The OpenDP pipeline for the query.
-    - `input_data_type` (str, optional): The type of input data ("df" for DataFrame, default: "df").
     - `dummy` (bool, optional): Whether to use a dummy dataset (default: False).
     - `nb_rows` (int, optional): The number of rows in the dummy dataset (default: 100).
     - `seed` (int, optional): The random seed for generating the dummy dataset (default: 42).
@@ -186,12 +184,10 @@ This function estimates the cost of executing an OpenDP query.
 
     res = client.estimate_opendp_cost(
         opendp_pipeline,
-        input_data_type="df",
     )
 
 Parameters:
     - `opendp_pipeline`: The OpenDP pipeline for the query.
-    - `input_data_type` (str, optional): The type of input data ("df" for DataFrame, default: "df").
 
 Returns:
     - `dict`: A dictionary containing the estimated cost.
diff --git a/client/lomas_client/client.py b/client/lomas_client/client.py
index 470eabc4..23a2c183 100644
--- a/client/lomas_client/client.py
+++ b/client/lomas_client/client.py
@@ -138,7 +138,6 @@ def estimate_smartnoise_cost(
     def opendp_query(
         self,
         opendp_pipeline: dp.Measurement,
-        input_data_type: str = "df",
         fixed_delta: Optional[float] = None,
         dummy: bool = False,
         nb_rows: int = DUMMY_NB_ROWS,
@@ -148,7 +147,6 @@ def opendp_query(
         body_json = {
             "dataset_name": self.dataset_name,
             "opendp_json": opendp_json,
-            "input_data_type": input_data_type,
             "fixed_delta": fixed_delta,
         }
         if dummy:
@@ -183,14 +181,12 @@ def opendp_query(
     def estimate_opendp_cost(
         self,
         opendp_pipeline: dp.Measurement,
-        input_data_type: str = "df",
         fixed_delta: Optional[float] = None,
     ) -> Optional[dict[str, float]]:
         opendp_json = opendp_pipeline.to_json()
         body_json = {
             "dataset_name": self.dataset_name,
             "opendp_json": opendp_json,
-            "input_data_type": input_data_type,
             "fixed_delta": fixed_delta,
         }
         res = self._exec("estimate_opendp_cost", body_json)
@@ -253,12 +249,14 @@ def get_previous_queries(self) -> Optional[List[dict]]:
 
             deserialised_queries = []
             for query in queries:
-                match query["api"]:
+                match query["dp_librairy"]:
                     case DPLibraries.SMARTNOISE_SQL:
                         pass
                     case DPLibraries.OPENDP:
-                        opdp_query = make_load_json(query["query"])
-                        query["query"] = opdp_query
+                        opdp_query = make_load_json(
+                            query["client_input"]["opendp_json"]
+                        )
+                        query["client_input"]["opendp_json"] = opdp_query
                     case _:
                         raise ValueError(
                             "Cannot deserialise unknown query type:"
diff --git a/client/notebooks/Demo_Client_Notebook.ipynb b/client/notebooks/Demo_Client_Notebook.ipynb
index f9db1246..48591bb2 100644
--- a/client/notebooks/Demo_Client_Notebook.ipynb
+++ b/client/notebooks/Demo_Client_Notebook.ipynb
@@ -1,1385 +1,1425 @@
 {
-    "cells": [
-        {
-            "cell_type": "markdown",
-            "id": "3f18d338",
-            "metadata": {},
-            "source": [
-                "# Secure Data Disclosure: Client side"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "1582a2ae",
-            "metadata": {},
-            "source": [
-                "This notebook showcases how researcher could use the Secure Data Disclosure system. It explains the different functionnalities provided by the `lomas-client` client library to interact with the secure server.\n",
-                "\n",
-                "The secure data are never visible by researchers. They can only access to differentially private responses via queries to the server.\n",
-                "\n",
-                "Each user has access to one or multiple projects and for each dataset has a limited budget with $\\epsilon$ and $\\delta$ values."
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 1,
-            "id": "23bb4f13-7800-41b2-b429-68c2d02243d0",
-            "metadata": {},
-            "outputs": [
-                {
-                    "data": {
-                        "image/png": "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P/i1WfzOMjsFhZBuOCe6juo8qnMqAABR0XeGX/z8D3YMQDEioEOr+fPfsEOJXnlloR1CsXhr4VLnJj5fIZ1+nYsHc012CoBC+MtfnkqozpoOBUAP/flJO4Z8Uxiabjjn9ecHn8j7DysAACSj7/b8YAQULwI6OJ5/boFzkxdEJTlU/bWcqAixqlO6f1FUb82WbuLvueePdgxAOXh70bt2KE5V2z/xiQ8lnK++dPvN5ripE+0z4nSephRdYSx6K3EfqcrQNde833z7O//Suo++9n8/by686Ez7jDhdY59/foEdAwAge/qe4P2O4P3TdWnOB893mlrwWvT2UjsEoNjQBl0BlEIbdKoyqVJZLt38ecd1o3HVVZfYsY4rlrbfikW620PPW7QouNRGPtosKNR+og264kIbdOEKdR73fyb05TqsDdB//ep3EkrbJTsX6DM9b97LZtmy1a0/xtTXD4md6yeZc889PWU7o25nCMuXrUp4T81j3PjR5uyzZwV2hJBuGyupzgXex3U++sAHzzN/e3xe63VKy3HBBbPN6WfMdMZFpdWeeur52HOWtC6zblLGjx9pZs8+qcPnTf86KUD1vq+XvypssmuptvGjj8519pFbelnhn5b34ovPCu1owr88Ombuv/9hszC2bbSv3XmoiQSXttfXv/FFO5ZIP9j98pdtVaD0feALX7jRjrXp6DHVkX2ZD7RBB5Q+2qBL7zu6/1qU7DUdvRaJ+9pknVulao8122u3e21qbNyUUBPIXYewtrz921XX62FDB5u//W1e63LoenjBhbMT2vDL5fej0aNHtFt3zWf27Fl522733/+IefyxZ+1YfDlWrFhj5se+M2j7aR5TY+t91VWXtl7Xw7axlrW+oa7g7aVnqtjboCOgK4BiD+j0gf7SF79px+InH32QvScpndS+852v2LHk9OV+wSsLW79suydEfbBXrVqT9KISdHLUF/1UJyv3pOSeTETzPiP2BT/oS346Fzf/TYQed09I3hsSd3t15ESUznJ4qYTMt+/8mR2LO2nW8YEdOLjbZMXy1QkXANH7BPXm5F+eIP5lDLsYuxeFZBfjoJtyraNu1txt7F4YZp95UtJGbTuyvl7F8KUiagR04Qp1Hle7j94vOzq/XHHFhVn1AvrjH/82IZzx0zF67TWXhQYiqgqj6pnuOS+MSpH5PyP5COh0/hfv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",
-                        "text/plain": [
-                            "<IPython.core.display.Image object>"
-                        ]
-                    },
-                    "execution_count": 1,
-                    "metadata": {
-                        "image/png": {
-                            "width": 800
-                        }
-                    },
-                    "output_type": "execute_result"
-                }
-            ],
-            "source": [
-                "from IPython.display import Image\n",
-                "Image(filename=\"images/image_demo_client.png\", width=800)"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "5b73135c",
-            "metadata": {},
-            "source": [
-                "🐧🐧🐧\n",
-                "In this notebook the researcher is a penguin researcher named Dr. Antarctica. She aims to do a grounbdbreaking research on various penguins dimensions.\n",
-                "\n",
-                "Therefore, the powerful queen Icerbegina 👑 had the data collected. But in order to get the penguins to agree to participate she promised them that no one would be able to look at the data and that no one would be able to guess the bill width of any specific penguin (which is very sensitive information) from the data. Nobody! Not even the researchers. The queen hence stored the data on the Secure Data Disclosure Server and only gave a small budget to Dr. Antarctica.\n",
-                "\n",
-                "This is not a problem for Dr. Antarctica as she does not need to see the data to make statistics thanks to the Secure Data Disclosure Client library `lomas-client`. \n",
-                "🐧🐧🐧"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "01ae30d2",
-            "metadata": {},
-            "source": [
-                "## Step 1: Install the library\n",
-                "To interact with the secure server on which the data is stored, Dr.Antartica first needs to install the library `lomas-client` on her local developping environment. \n",
-                "\n",
-                "It can be installed via the pip command:"
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 2,
-            "id": "28fbdd79-8c15-49a9-bcf9-fcdeac09d2b5",
-            "metadata": {},
-            "outputs": [],
-            "source": [
-                "!pip install opendp-logger\n",
-                "!pip install lomas-client"
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 3,
-            "id": "6fb569fc",
-            "metadata": {},
-            "outputs": [],
-            "source": [
-                "from lomas_client import Client\n",
-                "import numpy as np"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "9c63718b",
-            "metadata": {},
-            "source": [
-                "## Step 2: Initialise the client\n",
-                "\n",
-                "Once the library is installed, a Client object must be created. It is responsible for sending sending requests to the server and processing responses in the local environment. It enables a seamless interaction with the server. \n",
-                "\n",
-                "To create the client, Dr. Antartica needs to give it a few parameters:\n",
-                "- a url: the root application endpoint to the remote secure server.\n",
-                "- user_name: her name as registered in the database (Dr. Alice Antartica)\n",
-                "- dataset_name: the name of the dataset that she wants to query (PENGUIN)\n",
-                "\n",
-                "She will only be able to query on the real dataset if the queen Icergina has previously made her an account in the database, given her access to the PENGUIN dataset and has given her some epsilon and delta credit (as is done in the Admin Notebook for Users and Datasets management)."
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 4,
-            "id": "941991f7",
-            "metadata": {},
-            "outputs": [],
-            "source": [
-                "# APP_URL = \"http://lomas_server_dev:80\"\n",
-                "APP_URL = \"https://lomas-server.lab.sspcloud.fr\"\n",
-                "USER_NAME = \"Dr. Antartica\"\n",
-                "DATASET_NAME = \"PENGUIN\"\n",
-                "client = Client(url=APP_URL, user_name = USER_NAME, dataset_name = DATASET_NAME)"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "0ec400c8",
-            "metadata": {},
-            "source": [
-                "And that's it for the preparation. She is now ready to use the various functionnalities offered by `lomas_client`."
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "9b9a5f13",
-            "metadata": {},
-            "source": [
-                "## Step 3: Understand the functionnalities of the library"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "c7cb5531",
-            "metadata": {},
-            "source": [
-                "### Getting dataset metadata\n",
-                "\n",
-                "Dr. Antartica has never seen the data and as a first step to understand what is available to her, she would like to check the metadata of the dataset. Therefore, she just needs to call the `get_dataset_metadata()` function of the client. As this is public information, this does not cost any budget.\n",
-                "\n",
-                "This function returns metadata information in a format based on [SmartnoiseSQL dictionary format](https://docs.smartnoise.org/sql/metadata.html#dictionary-format), where among other, there is information about all the available columns, their type, bound values (see Smartnoise page for more details). Any metadata is required for Smartnoise-SQL is also required here and additional information such that the different categories in a string type column column can be added."
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 5,
-            "id": "0fdebac9-57fc-4410-878b-5a77425af634",
-            "metadata": {},
-            "outputs": [
-                {
-                    "data": {
-                        "text/plain": [
-                            "{'max_ids': 1,\n",
-                            " 'row_privacy': True,\n",
-                            " 'censor_dims': False,\n",
-                            " 'species': {'type': 'string',\n",
-                            "  'cardinality': 3,\n",
-                            "  'categories': ['Adelie', 'Chinstrap', 'Gentoo']},\n",
-                            " 'island': {'type': 'string',\n",
-                            "  'cardinality': 3,\n",
-                            "  'categories': ['Torgersen', 'Biscoe', 'Dream']},\n",
-                            " 'bill_length_mm': {'type': 'float', 'lower': 30.0, 'upper': 65.0},\n",
-                            " 'bill_depth_mm': {'type': 'float', 'lower': 13.0, 'upper': 23.0},\n",
-                            " 'flipper_length_mm': {'type': 'float', 'lower': 150.0, 'upper': 250.0},\n",
-                            " 'body_mass_g': {'type': 'float', 'lower': 2000.0, 'upper': 7000.0},\n",
-                            " 'sex': {'type': 'string', 'cardinality': 2, 'categories': ['MALE', 'FEMALE']}}"
-                        ]
-                    },
-                    "execution_count": 5,
-                    "metadata": {},
-                    "output_type": "execute_result"
-                }
-            ],
-            "source": [
-                "penguin_metadata = client.get_dataset_metadata()\n",
-                "penguin_metadata"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "d338ed96",
-            "metadata": {},
-            "source": [
-                "Based on this Dr. Antartica knows that there are 7 columns, 3 of string type (species, island, sex) with their associated categories (i.e. the species column has 3 possibilities: 'Adelie', 'Chinstrap', 'Gentoo') and 4 of float type (bill length, bill depth, flipper length and body mass) with their associated bounds (i.e. the body mass of penguin ranges from 2000 to 7000 gramms). She also knows based on the field `max_ids: 1` that each penguin can only be once in the dataset and on the field `row_privacy: True` that each row represents a single penguin. "
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "5a3c899d",
-            "metadata": {},
-            "source": [
-                "### Get a dummy dataset\n",
-                "\n",
-                "Now, that she has seen and understood the metadata, she wants to get an even better understanding of the dataset (but is still not able to see it). A solution to have an idea of what the dataset looks like it to create a dummy dataset. \n",
-                "\n",
-                "Based on the public metadata of the dataset, a random dataframe can be created created. By default, there will be 100 rows and the seed is set to 42 to ensure reproducibility, but these 2 variables can be changed to obtain different dummy datasets.\n",
-                "Getting a dummy dataset does not affect the budget as there is no differential privacy here. It is not a synthetic dataset and all that could be learn here is already present in the public metadata (it is created randomly on the fly based on the metadata).\n",
-                "\n",
-                "Dr. Antartica first create a dummy dataset with 200 rows and chooses a seed of 0."
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 6,
-            "id": "01f4365a",
-            "metadata": {},
-            "outputs": [],
-            "source": [
-                "NB_ROWS = 200\n",
-                "SEED = 0"
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 7,
-            "id": "3f553b29",
-            "metadata": {},
-            "outputs": [
-                {
-                    "name": "stdout",
-                    "output_type": "stream",
-                    "text": [
-                        "(200, 7)\n"
-                    ]
-                },
-                {
-                    "data": {
-                        "text/html": [
-                            "<div>\n",
-                            "<style scoped>\n",
-                            "    .dataframe tbody tr th:only-of-type {\n",
-                            "        vertical-align: middle;\n",
-                            "    }\n",
-                            "\n",
-                            "    .dataframe tbody tr th {\n",
-                            "        vertical-align: top;\n",
-                            "    }\n",
-                            "\n",
-                            "    .dataframe thead th {\n",
-                            "        text-align: right;\n",
-                            "    }\n",
-                            "</style>\n",
-                            "<table border=\"1\" class=\"dataframe\">\n",
-                            "  <thead>\n",
-                            "    <tr style=\"text-align: right;\">\n",
-                            "      <th></th>\n",
-                            "      <th>species</th>\n",
-                            "      <th>island</th>\n",
-                            "      <th>bill_length_mm</th>\n",
-                            "      <th>bill_depth_mm</th>\n",
-                            "      <th>flipper_length_mm</th>\n",
-                            "      <th>body_mass_g</th>\n",
-                            "      <th>sex</th>\n",
-                            "    </tr>\n",
-                            "  </thead>\n",
-                            "  <tbody>\n",
-                            "    <tr>\n",
-                            "      <th>0</th>\n",
-                            "      <td>Gentoo</td>\n",
-                            "      <td>Biscoe</td>\n",
-                            "      <td>49.208473</td>\n",
-                            "      <td>16.117959</td>\n",
-                            "      <td>190.125950</td>\n",
-                            "      <td>2873.291927</td>\n",
-                            "      <td>FEMALE</td>\n",
-                            "    </tr>\n",
-                            "    <tr>\n",
-                            "      <th>1</th>\n",
-                            "      <td>Gentoo</td>\n",
-                            "      <td>Torgersen</td>\n",
-                            "      <td>55.031628</td>\n",
-                            "      <td>19.963435</td>\n",
-                            "      <td>242.929142</td>\n",
-                            "      <td>3639.940005</td>\n",
-                            "      <td>FEMALE</td>\n",
-                            "    </tr>\n",
-                            "    <tr>\n",
-                            "      <th>2</th>\n",
-                            "      <td>Chinstrap</td>\n",
-                            "      <td>Torgersen</td>\n",
-                            "      <td>51.096718</td>\n",
-                            "      <td>16.777518</td>\n",
-                            "      <td>159.961493</td>\n",
-                            "      <td>5401.743330</td>\n",
-                            "      <td>MALE</td>\n",
-                            "    </tr>\n",
-                            "    <tr>\n",
-                            "      <th>3</th>\n",
-                            "      <td>Adelie</td>\n",
-                            "      <td>Biscoe</td>\n",
-                            "      <td>49.070911</td>\n",
-                            "      <td>14.796037</td>\n",
-                            "      <td>244.530153</td>\n",
-                            "      <td>2316.038092</td>\n",
-                            "      <td>MALE</td>\n",
-                            "    </tr>\n",
-                            "    <tr>\n",
-                            "      <th>4</th>\n",
-                            "      <td>Chinstrap</td>\n",
-                            "      <td>Biscoe</td>\n",
-                            "      <td>44.827918</td>\n",
-                            "      <td>13.246787</td>\n",
-                            "      <td>236.948853</td>\n",
-                            "      <td>5036.246870</td>\n",
-                            "      <td>FEMALE</td>\n",
-                            "    </tr>\n",
-                            "  </tbody>\n",
-                            "</table>\n",
-                            "</div>"
-                        ],
-                        "text/plain": [
-                            "     species     island  bill_length_mm  bill_depth_mm  flipper_length_mm   \n",
-                            "0     Gentoo     Biscoe       49.208473      16.117959         190.125950  \\\n",
-                            "1     Gentoo  Torgersen       55.031628      19.963435         242.929142   \n",
-                            "2  Chinstrap  Torgersen       51.096718      16.777518         159.961493   \n",
-                            "3     Adelie     Biscoe       49.070911      14.796037         244.530153   \n",
-                            "4  Chinstrap     Biscoe       44.827918      13.246787         236.948853   \n",
-                            "\n",
-                            "   body_mass_g     sex  \n",
-                            "0  2873.291927  FEMALE  \n",
-                            "1  3639.940005  FEMALE  \n",
-                            "2  5401.743330    MALE  \n",
-                            "3  2316.038092    MALE  \n",
-                            "4  5036.246870  FEMALE  "
-                        ]
-                    },
-                    "execution_count": 7,
-                    "metadata": {},
-                    "output_type": "execute_result"
-                }
-            ],
-            "source": [
-                "df_dummy = client.get_dummy_dataset(\n",
-                "    nb_rows = NB_ROWS, \n",
-                "    seed = SEED\n",
-                ")\n",
-                "\n",
-                "print(df_dummy.shape)\n",
-                "df_dummy.head()"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "98e6fda2-dde7-4f8b-a787-c9a1e3571ebe",
-            "metadata": {},
-            "source": [
-                "### Query on dummy dataset\n",
-                "Now that she has an idea of what the data looks like, she wants to start querying the real dataset for her research. \n",
-                "\n",
-                "However, her budget is limited and it would be a waste to spend it by mistake on a coding error. Therefore the client/server pipeline has functionnal testing capabilities for the users. It is possible to test a query on a `dummy` dataset to ensure that everything is working properly. Dr. Antartica will not be able to use the results of a dummy query for her analysis (as the data is random) but if the query on the dummy dataset works, she can be confident that her query will also work on the real dataset.\n",
-                "This functionnal testing on the dummy does not have any impact on the budget as it is on random data only.\n",
-                "\n",
-                "To test on the dummy data instead of the real data, the function call is exactly the same with the only exception of the flag `dummy=True`. In the following cell, she will test with `smartnoise_query` but it is the same flag for `opendp_query`. She can optionnaly give two additional parameters to set the seed and the number of rows of the dummy dataset.\n",
-                "\n",
-                "Another more advanced possibility for functionnal tests with the dummy is to compare results of queries on a local dummy and the remote dummy with a very high budget: \n",
-                "- create a local dummy on the notebook with a specific seed and number of rows\n",
-                "- compute locally the wanted query on this local dummy with python functions like numpy\n",
-                "- query the server on the same remote dummy with (`dummy=True`, same seed and same number of row) and a very big buget to limit noise as much as possible (don't worry this won't cost any real budget)\n",
-                "- compare and verify that the local and remote dummy have similar results."
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "243c73e3-daec-45d6-a3c8-ae1d60439ec4",
-            "metadata": {},
-            "source": [
-                "#### Average and number of rows with smartnoise-sql library on remote dummy"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "d1f8ea18-ccab-4f75-9490-b4d1144b39db",
-            "metadata": {},
-            "source": [
-                "Dr. Antartica will now try a query to get the number of penguin and their average bill length (in mm) on the dummy dataset. She does not forget to \n",
-                "- set the `dummy` flag to True\n",
-                "- set very high budget values to be able to compare results with a similar local dummy (with the same seed and number of rows) if she wants to verify that the function do what is expected. Here she will just check that the number of rows is close to what she sets as parameter."
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 8,
-            "id": "3946425d",
-            "metadata": {},
-            "outputs": [],
-            "source": [
-                "# Number of penguin and average bill length in mm\n",
-                "QUERY = \"SELECT COUNT(*) AS nb_penguins, \\\n",
-                "        AVG(bill_length_mm) AS avg_bill_length_mm \\\n",
-                "        FROM Schema.Table\""
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 9,
-            "id": "90cf2a6d",
-            "metadata": {},
-            "outputs": [],
-            "source": [
-                "# On the remote server dummy dataframe\n",
-                "dummy_res = client.smartnoise_query(\n",
-                "    query = QUERY,  \n",
-                "    epsilon = 100.0,\n",
-                "    delta = 0.99,\n",
-                "    dummy = True, \n",
-                "    nb_rows = NB_ROWS,\n",
-                "    seed = SEED\n",
-                ")"
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 10,
-            "id": "a30f277e",
-            "metadata": {},
-            "outputs": [
-                {
-                    "name": "stdout",
-                    "output_type": "stream",
-                    "text": [
-                        "Average bill length in remote dummy: 47.51mm.\n",
-                        "Number of rows in remote dummy: 200.\n"
-                    ]
-                }
-            ],
-            "source": [
-                "print(f\"Average bill length in remote dummy: {np.round(dummy_res['query_response']['avg_bill_length_mm'][0], 2)}mm.\")\n",
-                "print(f\"Number of rows in remote dummy: {np.round(dummy_res['query_response']['nb_penguins'][0], 2)}.\")"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "167e8c6d-6c93-4ab4-9ba7-bf7e783a6bc2",
-            "metadata": {},
-            "source": [
-                "No functionnal errors happened and the estimated number of rows is very close (if not equal) to the number of rows that she set for the dummy dataframe. She is now even more confident in using her query on the server."
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "324454ed",
-            "metadata": {},
-            "source": [
-                "### Get current budget\n",
-                "\n",
-                "It is the first time that Dr. Antartica connects to the server and she wants to know how much buget the queen assigned her.\n",
-                "Therefore, she calls the fonction `get_initial_budget`."
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 11,
-            "id": "61a467f3",
-            "metadata": {},
-            "outputs": [
-                {
-                    "data": {
-                        "text/plain": [
-                            "{'initial_epsilon': 10, 'initial_delta': 0.005}"
-                        ]
-                    },
-                    "execution_count": 11,
-                    "metadata": {},
-                    "output_type": "execute_result"
-                }
-            ],
-            "source": [
-                "client.get_initial_budget()"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "bc8f7a74",
-            "metadata": {},
-            "source": [
-                "She sees that she has 10.0 epsilon and 0.005 epsilon at her disposal.\n",
-                "\n",
-                "Then she checks her total spent budget `get_total_spent_budget`. As she only did queries on metadata on dummy dataframes, this should still be 0."
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 12,
-            "id": "afd22f84",
-            "metadata": {},
-            "outputs": [
-                {
-                    "data": {
-                        "text/plain": [
-                            "{'total_spent_epsilon': 0, 'total_spent_delta': 0}"
-                        ]
-                    },
-                    "execution_count": 12,
-                    "metadata": {},
-                    "output_type": "execute_result"
-                }
-            ],
-            "source": [
-                "client.get_total_spent_budget()"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "05daf5a4",
-            "metadata": {},
-            "source": [
-                "It will also be useful to know what the remaining budget is. Therefore, she calls the function `get_remaining_budget`. It just substarcts the total spent budget from the initial budget."
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 13,
-            "id": "6260cf54",
-            "metadata": {},
-            "outputs": [
-                {
-                    "data": {
-                        "text/plain": [
-                            "{'remaining_epsilon': 10, 'remaining_delta': 0.005}"
-                        ]
-                    },
-                    "execution_count": 13,
-                    "metadata": {},
-                    "output_type": "execute_result"
-                }
-            ],
-            "source": [
-                "client.get_remaining_budget()"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "20298e00",
-            "metadata": {},
-            "source": [
-                "As expected, for now the remaining budget is equal to the inital budget."
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "b746374c",
-            "metadata": {},
-            "source": [
-                "### Estimate cost of a query\n",
-                "Another safeguard is the functionnality to estimate the cost of a query. As in OpenDP and SmartnoiseSQL, the budget that will by used by a query might be slightly different than what is asked by the user. The `estimate cost` function returns the estimated real cost of any query.\n",
-                "\n",
-                "Again, of course, this will not impact the user's budget.\n",
-                "\n",
-                "Dr. Antartica checks the budget that computing the average bill length will really cost her if she asks the query with an `epsilon` and a `delta`."
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 14,
-            "id": "fd5ed08a",
-            "metadata": {},
-            "outputs": [],
-            "source": [
-                "EPSILON = 0.5\n",
-                "DELTA = 1e-4"
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 15,
-            "id": "133020c6",
-            "metadata": {},
-            "outputs": [
-                {
-                    "data": {
-                        "text/plain": [
-                            "{'epsilon_cost': 1.5, 'delta_cost': 0.00014999500000001387}"
-                        ]
-                    },
-                    "execution_count": 15,
-                    "metadata": {},
-                    "output_type": "execute_result"
-                }
-            ],
-            "source": [
-                "client.estimate_smartnoise_cost(\n",
-                "    query = QUERY, \n",
-                "    epsilon = EPSILON, \n",
-                "    delta = DELTA\n",
-                ")"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "3c6a3a8c",
-            "metadata": {},
-            "source": [
-                "This query would actually cost her 1.5 epsilon and delta 1.4999e-4. She decides that it is good enough."
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "e5379edf",
-            "metadata": {},
-            "source": [
-                "### Query on real private dataset with smartnoise-sql\n",
-                "Now that all the safeguard functions were tested, Dr. Antartica is ready to query on the real dataset and get a differentially private response of the number of penguins and average bill length. By default, the flag `dummy` is False so setting it is optional. She uses the values of `epsilon` and `delta` that she selected just before.\n",
-                "\n",
-                "Careful: This command DOES spend the budget of the user and the remaining budget is updated for every query."
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 16,
-            "id": "19e60263",
-            "metadata": {},
-            "outputs": [
-                {
-                    "data": {
-                        "text/plain": [
-                            "{'remaining_epsilon': 10, 'remaining_delta': 0.005}"
-                        ]
-                    },
-                    "execution_count": 16,
-                    "metadata": {},
-                    "output_type": "execute_result"
-                }
-            ],
-            "source": [
-                "client.get_remaining_budget()"
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 17,
-            "id": "69767fac",
-            "metadata": {},
-            "outputs": [],
-            "source": [
-                "response = client.smartnoise_query(\n",
-                "    query = QUERY,  \n",
-                "    epsilon = EPSILON, \n",
-                "    delta = DELTA,\n",
-                "    dummy = False # Optionnal\n",
-                ")"
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 18,
-            "id": "6dbbdf93",
-            "metadata": {},
-            "outputs": [
-                {
-                    "name": "stdout",
-                    "output_type": "stream",
-                    "text": [
-                        "Number of penguins in real data: 344.\n",
-                        "Average bill length of penguins in real data: 43.77mm.\n"
-                    ]
-                }
-            ],
-            "source": [
-                "nb_penguins = response['query_response']['nb_penguins'].iloc[0]\n",
-                "print(f\"Number of penguins in real data: {nb_penguins}.\")\n",
-                "\n",
-                "avg_bill_length = np.round(response['query_response']['avg_bill_length_mm'].iloc[0], 2)\n",
-                "print(f\"Average bill length of penguins in real data: {avg_bill_length}mm.\")"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "b2767e65",
-            "metadata": {},
-            "source": [
-                "After each query on the real dataset, the budget informations are also returned to the researcher. It is possible possible to check the remaining budget again afterwards:"
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 19,
-            "id": "4ced8a56-e2c3-4bd1-b94b-95cbbcd58a15",
-            "metadata": {},
-            "outputs": [
-                {
-                    "data": {
-                        "text/plain": [
-                            "{'requested_by': 'Dr. Antartica',\n",
-                            " 'query_response':    nb_penguins  avg_bill_length_mm\n",
-                            " 0          344           43.774276,\n",
-                            " 'spent_epsilon': 1.5,\n",
-                            " 'spent_delta': 0.00014999500000001387}"
-                        ]
-                    },
-                    "execution_count": 19,
-                    "metadata": {},
-                    "output_type": "execute_result"
-                }
-            ],
-            "source": [
-                "response"
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 20,
-            "id": "39701fe5",
-            "metadata": {},
-            "outputs": [
-                {
-                    "data": {
-                        "text/plain": [
-                            "{'remaining_epsilon': 8.5, 'remaining_delta': 0.004850004999999986}"
-                        ]
-                    },
-                    "execution_count": 20,
-                    "metadata": {},
-                    "output_type": "execute_result"
-                }
-            ],
-            "source": [
-                "client.get_remaining_budget()"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "e37c587f",
-            "metadata": {},
-            "source": [
-                "As can be seen in `get_total_spent_budget()`, it is the budget estimated with `estimate_smartnoise_cost()` that was spent."
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 21,
-            "id": "487f835f",
-            "metadata": {},
-            "outputs": [
-                {
-                    "data": {
-                        "text/plain": [
-                            "{'total_spent_epsilon': 1.5, 'total_spent_delta': 0.00014999500000001387}"
-                        ]
-                    },
-                    "execution_count": 21,
-                    "metadata": {},
-                    "output_type": "execute_result"
-                }
-            ],
-            "source": [
-                "client.get_total_spent_budget()"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "eef4afcd",
-            "metadata": {},
-            "source": [
-                "Dr. Antartica has now a differentially private estimation of the number of penguins in the dataset and is confident to use the library for the rest of her analyses."
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "04929993",
-            "metadata": {},
-            "source": [
-                "## Step 4: Penguin statistics with opendp"
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 22,
-            "id": "b9685226",
-            "metadata": {},
-            "outputs": [],
-            "source": [
-                "import opendp as dp\n",
-                "import opendp.transformations as trans\n",
-                "import opendp.measurements as meas"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "bbbca191",
-            "metadata": {},
-            "source": [
-                "### Confidence intervals for bill length over the whole population"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "9d41bd58",
-            "metadata": {},
-            "source": [
-                "She is first interested to have a better idea of the distribution of bill length of all species. She already has the count and average from the previous step, so she only needs the variance values.\n",
-                "\n",
-                "She first checks the metadata again to use the relevant values in the pipeline."
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 23,
-            "id": "4331d86f",
-            "metadata": {},
-            "outputs": [
-                {
-                    "data": {
-                        "text/plain": [
-                            "{'max_ids': 1,\n",
-                            " 'row_privacy': True,\n",
-                            " 'censor_dims': False,\n",
-                            " 'species': {'type': 'string',\n",
-                            "  'cardinality': 3,\n",
-                            "  'categories': ['Adelie', 'Chinstrap', 'Gentoo']},\n",
-                            " 'island': {'type': 'string',\n",
-                            "  'cardinality': 3,\n",
-                            "  'categories': ['Torgersen', 'Biscoe', 'Dream']},\n",
-                            " 'bill_length_mm': {'type': 'float', 'lower': 30.0, 'upper': 65.0},\n",
-                            " 'bill_depth_mm': {'type': 'float', 'lower': 13.0, 'upper': 23.0},\n",
-                            " 'flipper_length_mm': {'type': 'float', 'lower': 150.0, 'upper': 250.0},\n",
-                            " 'body_mass_g': {'type': 'float', 'lower': 2000.0, 'upper': 7000.0},\n",
-                            " 'sex': {'type': 'string', 'cardinality': 2, 'categories': ['MALE', 'FEMALE']}}"
-                        ]
-                    },
-                    "execution_count": 23,
-                    "metadata": {},
-                    "output_type": "execute_result"
-                }
-            ],
-            "source": [
-                "penguin_metadata"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "f90e0425",
-            "metadata": {},
-            "source": [
-                "She can define the columns names and the bounds of the relevant column."
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 24,
-            "id": "ff8cb7b6",
-            "metadata": {},
-            "outputs": [],
-            "source": [
-                "columns = [\"species\", \"island\", \"bill_length_mm\", \"bill_depth_mm\", \"flipper_length_mm\", \"body_mass_g\", \"sex\"]"
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 25,
-            "id": "70b2bdb1",
-            "metadata": {},
-            "outputs": [
-                {
-                    "data": {
-                        "text/plain": [
-                            "(30.0, 65.0)"
-                        ]
-                    },
-                    "execution_count": 25,
-                    "metadata": {},
-                    "output_type": "execute_result"
-                }
-            ],
-            "source": [
-                "bill_length_min = penguin_metadata['bill_length_mm']['lower']\n",
-                "bill_length_max = penguin_metadata['bill_length_mm']['upper']\n",
-                "bill_length_min, bill_length_max"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "e93ae087",
-            "metadata": {},
-            "source": [
-                "She can now define the pipeline of the transformation to have the variance that she wants on the data:"
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 26,
-            "id": "75e4933b",
-            "metadata": {},
-            "outputs": [],
-            "source": [
-                "bill_length_transformation_pipeline = (\n",
-                "    trans.make_split_dataframe(separator=\",\", col_names=columns) >>\n",
-                "    trans.make_select_column(key=\"bill_length_mm\", TOA=str) >>\n",
-                "    trans.then_cast_default(TOA=float) >>\n",
-                "    trans.then_clamp(bounds=(bill_length_min, bill_length_max)) >>\n",
-                "    trans.then_resize(size=nb_penguins.tolist(), constant=avg_bill_length) >>\n",
-                "    trans.then_variance()\n",
-                ")"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "411d464c",
-            "metadata": {},
-            "source": [
-                "However, when she tries to execute it on the server, she has an error (see below). "
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 27,
-            "id": "8041a647",
-            "metadata": {},
-            "outputs": [
-                {
-                    "name": "stdout",
-                    "output_type": "stream",
-                    "text": [
-                        "Server error status 400: {\"InvalidQueryException\":\"The pipeline provided is not a measurement. It cannot be processed in this server.\"}\n"
-                    ]
-                }
-            ],
-            "source": [
-                "# Expect to fail !!!\n",
-                "client.opendp_query(\n",
-                "    opendp_pipeline = bill_length_transformation_pipeline,\n",
-                "    dummy=True\n",
-                ")"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "d06c59dc",
-            "metadata": {},
-            "source": [
-                "This is because the server will only allow measurement pipeline with differentially private results. She adds Laplacian noise to the pipeline and should be able to instantiate the pipeline."
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 28,
-            "id": "b8162859",
-            "metadata": {},
-            "outputs": [],
-            "source": [
-                "var_bill_length_measurement_pipeline = (\n",
-                "    bill_length_transformation_pipeline >>\n",
-                "    meas.then_laplace(scale=5.0)\n",
-                ")"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "fc7e0ecd",
-            "metadata": {},
-            "source": [
-                "Now that there is a measurement, she is able to apply the pipeline on the dummy dataset of the server."
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 29,
-            "id": "df61bce0",
-            "metadata": {},
-            "outputs": [
-                {
-                    "name": "stdout",
-                    "output_type": "stream",
-                    "text": [
-                        "Dummy result for variance: 27.71\n"
-                    ]
-                }
-            ],
-            "source": [
-                "dummy_var_res = client.opendp_query(\n",
-                "    opendp_pipeline = var_bill_length_measurement_pipeline, \n",
-                "    dummy=True\n",
-                ")\n",
-                "print(f\"Dummy result for variance: {np.round(dummy_var_res['query_response'], 2)}\")"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "ded11ac4",
-            "metadata": {},
-            "source": [
-                "With opendp, the function `estimate_opendp_cost` is particularly useful to estimate the used `epsilon` and `delta` based on the `scale` value."
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 30,
-            "id": "7ae7f735",
-            "metadata": {},
-            "outputs": [
-                {
-                    "data": {
-                        "text/plain": [
-                            "{'epsilon_cost': 0.7122093023265229, 'delta_cost': 0}"
-                        ]
-                    },
-                    "execution_count": 30,
-                    "metadata": {},
-                    "output_type": "execute_result"
-                }
-            ],
-            "source": [
-                "cost_res = client.estimate_opendp_cost(\n",
-                "    opendp_pipeline = var_bill_length_measurement_pipeline\n",
-                ")\n",
-                "cost_res"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "1c791d36",
-            "metadata": {},
-            "source": [
-                "She can now execute the query on the real dataset."
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 31,
-            "id": "085555a5",
-            "metadata": {},
-            "outputs": [],
-            "source": [
-                "var_res = client.opendp_query(\n",
-                "    opendp_pipeline = var_bill_length_measurement_pipeline, \n",
-                ")"
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 32,
-            "id": "674332e7",
-            "metadata": {},
-            "outputs": [
-                {
-                    "name": "stdout",
-                    "output_type": "stream",
-                    "text": [
-                        "Number of penguins: 344 (from previous smartnoise-sql query).\n",
-                        "Average bill length: 43.77 (from previous smartnoise-sql query).\n",
-                        "Variance of bill length: 18.782 (from opendp query).\n"
-                    ]
-                }
-            ],
-            "source": [
-                "print(f\"Number of penguins: {nb_penguins} (from previous smartnoise-sql query).\")\n",
-                "\n",
-                "print(f\"Average bill length: {np.round(avg_bill_length, 2)} (from previous smartnoise-sql query).\")\n",
-                "\n",
-                "var_bill_length = var_res['query_response']\n",
-                "print(f\"Variance of bill length: {np.round(var_bill_length, 3)} (from opendp query).\")"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "367081be-1159-45d8-9129-88fba20fb697",
-            "metadata": {},
-            "source": [
-                "She can now do all the postprocessing that she wants with the returned data without adding any privacy risk. "
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 33,
-            "id": "f72b19d0",
-            "metadata": {},
-            "outputs": [
-                {
-                    "name": "stdout",
-                    "output_type": "stream",
-                    "text": [
-                        "Standard error of bill length: 0.23.\n"
-                    ]
-                }
-            ],
-            "source": [
-                "# Get standard error\n",
-                "standard_error = np.sqrt(var_bill_length/nb_penguins)\n",
-                "print(f\"Standard error of bill length: {np.round(standard_error, 2)}.\")"
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 34,
-            "id": "62630a03",
-            "metadata": {},
-            "outputs": [
-                {
-                    "name": "stdout",
-                    "output_type": "stream",
-                    "text": [
-                        "The 95% confidence interval of the bill length of all penguins is [43.31, 44.23].\n"
-                    ]
-                }
-            ],
-            "source": [
-                " # Compute the 95% confidence interval\n",
-                "ZSCORE = 1.96\n",
-                "lower_bound = np.round(avg_bill_length - ZSCORE*standard_error, 2)\n",
-                "upper_bound = np.round(avg_bill_length + ZSCORE*standard_error, 2)\n",
-                "print(f\"The 95% confidence interval of the bill length of all penguins is [{lower_bound}, {upper_bound}].\")"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "0d30d98e-26f4-44ec-a0f0-7a039f344860",
-            "metadata": {},
-            "source": [
-                "### Count per species"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "b6a3cc00-8734-4479-81a3-781c91b8eb06",
-            "metadata": {},
-            "source": [
-                "She can also creates an histogram of the number of penguin per species.\n",
-                "\n",
-                "She first extract the categories from the metadata:"
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 35,
-            "id": "558916a6-78a9-4589-abe8-41472f0c66d7",
-            "metadata": {},
-            "outputs": [
-                {
-                    "data": {
-                        "text/plain": [
-                            "['Adelie', 'Chinstrap', 'Gentoo']"
-                        ]
-                    },
-                    "execution_count": 35,
-                    "metadata": {},
-                    "output_type": "execute_result"
-                }
-            ],
-            "source": [
-                "categories = penguin_metadata['species']['categories']\n",
-                "categories"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "5f05aeb0-42d1-4444-a458-d2989494f544",
-            "metadata": {},
-            "source": [
-                "Then, writes the pipeline:"
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 36,
-            "id": "505a2793-6750-4f2a-9a9d-09f3a4ae4099",
-            "metadata": {},
-            "outputs": [],
-            "source": [
-                "species_count_pipeline = (\n",
-                "    trans.make_split_dataframe(separator=\",\", col_names=columns) >>\n",
-                "    trans.make_select_column(key=\"species\", TOA=str) >>\n",
-                "    trans.then_count_by_categories(categories=categories) >>\n",
-                "    meas.then_laplace(scale=0.5)\n",
-                ")"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "0f4109a9-c2f2-4365-bfa1-b5b2512919f9",
-            "metadata": {},
-            "source": [
-                "Verify it works on the dummy:"
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 37,
-            "id": "712b1c74-cac6-4b3f-9421-8d8ffa9debc7",
-            "metadata": {},
-            "outputs": [
-                {
-                    "name": "stdout",
-                    "output_type": "stream",
-                    "text": [
-                        "Dummy result for histogram: [38, 34, 29, 0]\n"
-                    ]
-                }
-            ],
-            "source": [
-                "dummy_res = client.opendp_query(\n",
-                "    opendp_pipeline = species_count_pipeline, \n",
-                "    dummy=True\n",
-                ")\n",
-                "print(f\"Dummy result for histogram: {dummy_res['query_response']}\")"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "66de7794-9aae-41d1-ba98-6b234a05d6f8",
-            "metadata": {},
-            "source": [
-                "Checks the required cost:"
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 38,
-            "id": "3f942b1b-94bc-468e-8374-3034f2e6b8ce",
-            "metadata": {},
-            "outputs": [
-                {
-                    "data": {
-                        "text/plain": [
-                            "{'epsilon_cost': 2.0, 'delta_cost': 0}"
-                        ]
-                    },
-                    "execution_count": 38,
-                    "metadata": {},
-                    "output_type": "execute_result"
-                }
-            ],
-            "source": [
-                "cost_res = client.estimate_opendp_cost(\n",
-                "    opendp_pipeline = species_count_pipeline\n",
-                ")\n",
-                "cost_res"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "1adfe446-ff13-41f4-9f3c-9998e2ae0f00",
-            "metadata": {},
-            "source": [
-                "And finally apply the pipeline on the real dataset:"
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 39,
-            "id": "c6fe47b7-048e-404a-bedb-720e734b0c70",
-            "metadata": {},
-            "outputs": [],
-            "source": [
-                "species_counts_res = client.opendp_query(\n",
-                "    opendp_pipeline = species_count_pipeline, \n",
-                ")"
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 40,
-            "id": "b8d5fd82-5ded-47ec-8135-f6870865055d",
-            "metadata": {
-                "scrolled": true
-            },
-            "outputs": [
-                {
-                    "name": "stdout",
-                    "output_type": "stream",
-                    "text": [
-                        "Species Adelie has 152 penguins.\n",
-                        "Species Chinstrap has 67 penguins.\n",
-                        "Species Gentoo has 124 penguins.\n",
-                        "Species Unknown has 0 penguins.\n"
-                    ]
-                }
-            ],
-            "source": [
-                "for i, count in enumerate(species_counts_res['query_response']):\n",
-                "    if i == len(categories):\n",
-                "        print(f\"Species Unknown has {count} penguins.\")\n",
-                "    else:\n",
-                "        print(f\"Species {categories[i]} has {count} penguins.\")"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "94eaf59b-c108-424c-8978-b1c86e141ccb",
-            "metadata": {},
-            "source": [
-                "## Step 5: See archives of queries"
-            ]
-        },
-        {
-            "cell_type": "markdown",
-            "id": "64003c53-de56-4bdc-a3c2-0c3e40031919",
-            "metadata": {},
-            "source": [
-                "She now wants to verify all the queries that she did on the real data. It is possible because an archive of all queries is kept in a secure database. With a function call she can see her queries, budget and associated responses."
-            ]
-        },
-        {
-            "cell_type": "code",
-            "execution_count": 41,
-            "id": "008fd230-cdfd-4e03-91ce-5a60b06c106d",
-            "metadata": {},
-            "outputs": [
-                {
-                    "data": {
-                        "text/plain": [
-                            "[{'user_name': 'Dr. Antartica',\n",
-                            "  'dataset_name': 'PENGUIN',\n",
-                            "  'response': {'requested_by': 'Dr. Antartica',\n",
-                            "   'query_response': {'index': [0],\n",
-                            "    'columns': ['nb_penguins', 'avg_bill_length_mm'],\n",
-                            "    'data': [[344, 43.77427628066385]],\n",
-                            "    'index_names': [None],\n",
-                            "    'column_names': [None]},\n",
-                            "   'spent_epsilon': 1.5,\n",
-                            "   'spent_delta': 0.00014999500000001387},\n",
-                            "  'timestamp': 1714031889.5089996,\n",
-                            "  'api': 'smartnoise_sql',\n",
-                            "  'query': 'SELECT COUNT(*) AS nb_penguins,         AVG(bill_length_mm) AS avg_bill_length_mm         FROM Schema.Table',\n",
-                            "  'epsilon_parameter': 0.5,\n",
-                            "  'delta_parameter': 0.0001,\n",
-                            "  'mechanisms': {},\n",
-                            "  'postprocess': True},\n",
-                            " {'user_name': 'Dr. Antartica',\n",
-                            "  'dataset_name': 'PENGUIN',\n",
-                            "  'response': {'requested_by': 'Dr. Antartica',\n",
-                            "   'query_response': 18.781917259710387,\n",
-                            "   'spent_epsilon': 0.7122093023265229,\n",
-                            "   'spent_delta': 0},\n",
-                            "  'timestamp': 1714031926.535139,\n",
-                            "  'api': 'opendp',\n",
-                            "  'query': <opendp.mod.Measurement at 0x7fed9327f770>,\n",
-                            "  'input_data_type': 'df',\n",
-                            "  'fixed_delta': None},\n",
-                            " {'user_name': 'Dr. Antartica',\n",
-                            "  'dataset_name': 'PENGUIN',\n",
-                            "  'response': {'requested_by': 'Dr. Antartica',\n",
-                            "   'query_response': [152, 67, 124, 0],\n",
-                            "   'spent_epsilon': 2.0,\n",
-                            "   'spent_delta': 0},\n",
-                            "  'timestamp': 1714031944.509833,\n",
-                            "  'api': 'opendp',\n",
-                            "  'query': <opendp.mod.Measurement at 0x7fed9327e840>,\n",
-                            "  'input_data_type': 'df',\n",
-                            "  'fixed_delta': None}]"
-                        ]
-                    },
-                    "execution_count": 41,
-                    "metadata": {},
-                    "output_type": "execute_result"
-                }
-            ],
-            "source": [
-                "previous_queries = client.get_previous_queries()\n",
-                "previous_queries"
-            ]
-        }
-    ],
-    "metadata": {
-        "kernelspec": {
-            "display_name": "Python 3 (ipykernel)",
-            "language": "python",
-            "name": "python3"
-        },
-        "language_info": {
-            "codemirror_mode": {
-                "name": "ipython",
-                "version": 3
-            },
-            "file_extension": ".py",
-            "mimetype": "text/x-python",
-            "name": "python",
-            "nbconvert_exporter": "python",
-            "pygments_lexer": "ipython3",
-            "version": "3.11.6"
-        }
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "id": "3f18d338",
+   "metadata": {},
+   "source": [
+    "# Secure Data Disclosure: Client side"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "1582a2ae",
+   "metadata": {},
+   "source": [
+    "This notebook showcases how researcher could use the Secure Data Disclosure system. It explains the different functionnalities provided by the `lomas-client` client library to interact with the secure server.\n",
+    "\n",
+    "The secure data are never visible by researchers. They can only access to differentially private responses via queries to the server.\n",
+    "\n",
+    "Each user has access to one or multiple projects and for each dataset has a limited budget with $\\epsilon$ and $\\delta$ values."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "id": "23bb4f13-7800-41b2-b429-68c2d02243d0",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAABOgAAAJOCAYAAAANqjggAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAJ10SURBVHhe7d0JlBx1oe/x/2SfJJNM9klmsq+EEEJCCGtYZF80AiIgCgpccUGP6MN3vd77fFflenmKxwWv+5WrIqIoKJuAEMIiIawhhIRsJJns2ySTZLLn9a/6XzPVNVW9TC/Vy/dzzpypqu6urq2run79X6qOxhgAAAAAAAAAkehk/wMAAAAAAACIAAEdAAAAAAAAECECOgAAAAAAACBCBHQAAAAAAABAhAjoAAAAAAAAgAgR0AEAAAAAAAARIqADAAAAAAAAIlR1NMYO58wtf11hhzLX0Keb6d6lk6mv6WZOrO9tJgyoto+g3Pxp8TazYsc+s2XPQbNr/2E71ZhBvbo6+39mbP/PGNbbTi0e//36ZjO/sdmOdUyf7p2dv5rY3/A+3c0ZI/s46w3kyjeeXWsadx2wY21mNdSYj58w2I4hKnPf22nue2urHUv048vG2qHcKOR7AQAAAOiYoitBpxvKFdv3mXmrd5m7Xlzv3GS+un63fRTl4LFlO8ztT7xnnljR5OxrbzgnCuze2LjH/OzVTc7+f3dbi32kfGidday/s6XF2Q7/+vQa8+MFG511BwAAAAAAlaXoq7gqxFBQo9JWKH0KoR5asr1dKBdG+//ulzdWREirUPL78zcQ0gEAAAAAUGFKpg06lTJS1UKULoWsCqEytf/QEfM/b26piOBK6/irNzjOAQAAAACoJCXVSYTa/aIkXWlS8PTs6l12LHMK6e59a4sdK2+q9qtqwAAAAAAAoDIUtJOIZI2Tqwrj5j0HnfbGVu7Y7wQyQdSBxGdOqqPziBJz78ItTruCftqfZ47s09pJghoz//vKnaGl5W47dVjk+z5ZJxHpNLiuY3zRpr3mpdg8wqr6alt8/ZwRdgzIHJ1EwEUnEQAAAEDxK5oSdOqt86Lx/cznTx7mBHBhPVoquKN0Uel5Z2twRw8fPKa/uXzygNb9fdaovuZzs4Y6wV2QV9aVflt0Chi1zv/rtPrQ9VRAWY6dYwAAAAAAgPaKsoqrAgyFNGEhnXq+JLwoHQqbgkrEje3fwwnk/LTfx/TrbscS7T+c8wKfkdF6zqrvbcfaW9/cvvQTAAAAAAAoP0VTxTVIsmo5mcxL7dat2LHPCYm8VQob+nQzA3t2NZMGVQcGRR2l5X5z4x6zbteB1vfr072zqY+9n0oJBlXR1LI9uaLJrIwtp7dampZxTL8e5ryxtaGBZSoKM19Y0xxbnv1my95DCdWH87UN/LRNtsfee2dse2g5tF2OGdQzdB+GVSMthup52VZx9crFMa79+/TKnWbr3oMJx46OOR0z9TXdOnz8qOr5wk17W/eZv0qu5ukc27H3OLG+d4erH+fzM6rto5KX+myFrUP3zlXO5yybdfDSfvVW1dZ6TI4d7yo5mYxet2RLS7t9qZKWg3p2cbbFzNgyqsRxKulUcc3XeSefx2QQvZ96h1b7jaL5avkvndAvJ+/hHkPrmuPndHe/urRe8XN8dzN1SM+09k8uuNtZy+Uuk44V7b+xsfV3j7dk55l0z1mah65rW2Pnce/6a/sOjB2bw2Prnur4BgAAABCuqAM6+den17S7GRLdFKRqo0s3FI++u6PdDXkQ3dAoPEt1YxV006vXfvXM4c5yPpBGT6Xnx25MvTcyqrL7+PKm0Hb3RDddHzt+UEY3frp5u3/R1sCb9CC6wbw4dkObz6AuXWH73b/t/MKOvauPG5iz9SqWgC7d4010/Eyr65X250/z/skrG9M+dlx6jyti+yfdUCQfn1GvHy/YmHHPwemsQ9Bx5p4HFDaq1+kgmvctM+vsWBsFoToPpLu9Vfr0hmmDky5jqoBOy6mOW1Kdd9RGZLrBS76OybB10edN2069PAetRzrXiVQ6cgzpWLhqysCkYW82oVm621nrP2dSf9N84HCH3yuT64iuIWeP7ut8TgEAAABkpuh7cVUpiCC6QdFfGN186oYknRt/0c2HbvL0uo7Qsnx//oa0buR08+6+j/6r5Eeym2TR41o+3YymQ/O968X1ad/wi7aVtpluSKOkZQ/at7qhV2cSlaJv7GY3TCbHm+j4UaiooCPZ50Z0jH1jXmNGx45Ly6PlSvUeov2cz8+oQt5MgxVx16EjtO3CwjlR6Tc/rc/PXt2U0fZWSTHto3TPB37qtEXLmc55x3u+Siafx2QYve73i7aGrscxAzteGlLz7ugxpH1598sbO7x/kslkO+u5+sys78BnWbT8Wo90j019lnU9i/oaAgAAAJSiog/oRoe0RSZvb9lrhxLpZjLZTXIY92ZUJRsy9as3Nmd0k6mSK+5Ncrq0fA/Gbn5S6ej6u3Tj972X1tuxwtHNoEqnhS27StukWzKrVKzasd8OtTeyNvjYd2/QMzneXLrRVsm4ZHSMhQUe6dBy6fOQTL4/owoIOrJ9XHqtjsVMqH1EhUVhdOz6S/9l81l1zweZrqeqswb1qJyMzlcqSRVGy5DPYzKMjrNkAa+q0XaUSqhlcwxp/+h4yGYeQbStMpmnliPT/S06H4eVTExF15BMPz8AAABApSv6gG5YTTc71F5QqQDdVGQTTsmf38nsplc3mG7bR+nq6E2TlitZOKHHsl1/UUcchbrBUkihKoMqRRRWdfSYQdUZV48udjpWw0rBqLRgWFXOTMNgPx2vYftW+yIXgYI+D2HHab4/owqSOlLqye+dkB8Awmh5koVF/tJcWk4FX9nQez78bma9Wndk/+p8pXYsw+TzmEwm2XlX1YA7Gujn6hjS8ZDp/klGn09tq3zTvkxWMjEdOpd35McuAAAAoFJ1/lqMHc6ZsBuShj7dzQlDe9mx9Azo2TV0fnU13drN75evbQq8SVbgceKw3ubDUwaa66cNNhNiN8tHjhqnIwe/w7EH9h48ErisCtWS3YTrpvDKyQPMP51YZy6d2N957uqd4aWkXCoddu3UQa3Ltjl2g7Sj5ZB9NFGvbp1Dt+OPXt4Y2tOp2kVS+0BfOGWYs2xDY9uva+dOgdtANF3PSRaS5sJLjbtDl0HUZlZQu11Bwo6VKUN6mlG1wdWlM6Ub97Dl1XZNRjf+b23ea55Ztcv8bUV4FUMdq0H7WDe8z4WEOv7927lTldkeO4Z0LPupoXe9h44lL22/oONOAem5Y2vNZ2cNdeatPx2nNbHXNzYfcD4zfoePHjUnx/adX74/o79ZuMVZPz+FNSpR5W6fVNtInyMde/5tJB0JXW6aMSRhXlrOjbuDQy1t7w8e03YeORBblrDtrO0TtJypzlX+7ZHqvFMV+5sd0I5jvo9JSbUuQWaP7GPGd7DDj78tbwo8b7vrc13sXK3jVOukba+218LWqzm23EEl+d5r2m8Wxc4FQTTfIAox0z2/a1vvOdC+UxS/oPe6/+1tTknLIN5jU+veNfY+Ycdm075DgccMAAAAgPaKPqCTdOenkjlz3wu+UfzECYOdDhAU+In+67W9YzdWQTdJulkMaug62Y2iblxuO7U+IdA6bkgvp8RD2I24qOODj04bnLBsp43o47xX0M1Yjy6dnMf9VLpi8ZbgamhatttPb0i4YdVyahsohHs79rqgGyz1uhr0XrmkkhbJggo12B900x4k6oBO75/s7x9rm53jTa8P2t6im32VFgxa5z/EbpyDAhQFw/98RuL+1fA5sRt2La//mNV760/Hp9czq3a2e66CHM3bv/10nKon3sGxx3X8DO0d7zlTDeOfMqLGXD1lkH1mm0J8Rn/31tZ221bhnwIyf2CobXTc4J7OegcZElunoONG+zKM3ut9se3+v06vd8IP/Sn8GtG3rcqygtq/Lg2eh4Klm2fUJZxHvNs56LgJ2pfJzlUKcz5z0lBzfF3ba9zzzjtbWwKPMc0rKMzJ9zEpqQI6J8Q/sa41NNP2DgqH0/XK+uDP+P86rd7ZZt7Ppobd40jHtz4v6rF7bP9qp83MOZOCz1+ZBnSat84fQYLO7xpWOKbekYMCa1fQe6lEZNBx5j82tV46NhWsvhhbNv9rtM8K8SMPAAAAUA6KvoprJhZuCr7Z0c1LWHVB9eypx/1Uskm9Kmbi2uPaBxIyKWD+Lt0oh/WQGNZBRlipq9dDqmTpPT5/8jA71p62zayAxutFVcgUJuTT1r3h4aWq2qqh9nQbHVePhEF/xdAzbToU7ihk0E1+kLAqfR+YFFziRtSbZBAFMenQTbbCgTA6fr530WinB1OVdFRJ0LDtXYjP6GdOqnN67VVo41ZzVPXSsB419bg+I7ly4bj2PQ373/uVdcHbU+Gstl8QbZ+wTg/S3ZcuHRNhx1hQRxbJRHFMerk9wXrXJ1nvqdkIKykoev87zx/lfA50vtUy6dgN286ZCvvs6JwRdu0RPabnpEslIoOuMcmOTa2jevsNsiDkWAcAAACQqKwCunW7gquSekuJBAm7mVvdlLpqqks3+GE3YqoGGCYshJNMbqrUZlBYG1BBpYz8dOOlG7Agi0JuDAtJJW4U1GXTzlWxi5dqqgsNqsLac9LrkgUSeizo2Aw6ZoKOOd2sq31AbX9VscumXalCfEb1XAUjCkhU4unr54xIu4p0tvQZSufztq45uASmSiMlo7Bf76F9rgBSJZoURn5u1lD7jNRSHS/HplgGr0Ick6mcMyb34Xv3zqrQ257aTrz9ifecHwwUDhfyfBT22VFomywE1GOZ9GYb1nFNqmMzrIftsGMdAAAAQKKyCujCGs9OVb2mumvwZkhWssuvvk94b7NhgYsMi93I5kJYj7a6mU/2/l5hYeHakBvDXNHy3XbqMKekm8IUhQ5BQZFuhu99a4sdKx8q5aXSRip5kyzUCLtxrgkJVr3CAgf/cTM2SWCs7a/qyPe9tdXp1OMbz67NOKiI8jPqp1KB6kn5/72wLmcN7ycL3L3Cqmsm67VaFDy6pbQUQLqlFZMFNH7JzlWSybwKcUwmo2VN9pnpqBOTlCLUvtMPBg8t2e6E1vpTr9dqYiCfpY3DjplkJbRdYT1CBwkLAvum2Kdhx00hQ0wAAACglFUdjbHDOaOb9yAq8aGbykylO7+w53WUwi3dDHsplAi6mU+1bmHLdvOMIaEBmkorBfVqqtIpukH3yuS5YRRWqK0nv0zmkSsKT1RqK0iybVYIYds6UwrmbpiWWDUvmVy9r5faP/RXx+xoSUWtjwK+sCrbUojPaBAFJyoJqk4QFOqlG8ipdJoCML+w9VC4HFYN0Cvs9WHv1xEdPVdJuuerQh2TYeuiY06lJPNB4bOCuEzp86wSa+oYItlnW6UPFXYH0Y8VftkcM5m8V9i2zoZ+gMlHkAoAAACUk6IvQRflr+9hJRZyKcqgyS9XpflyQdslqN0xeX5NeDtQUXPbvNOfbkoVNihECqK2u74/f0PS9t3yTZ2A+Km6ZLqhoZfWx60CmE012Ewk+4wqlFPIouW568X1zrIpcMl1+OBVTJ+hfGg+kP9zYtAxGWag7VAkH1QtOuwclIyuWfqh4xvzGp0fPWDMeqq5AgAAACkVfUCXrLpTqupgKG1hJS6S9UhYTLT8KgmkEj5hN/q6mf+fN7dEGtL5KZxTSKeSVpm0g+hSaKbSOpl2spJLKtmlUC6ot1AgXersIVnInozablRQl24HNwAAAAAqW9EHdOuTlHZJ1W4VMpNsW0chrN2xUmvTSIGXelIMK5WmG/liDOlUDVK9s6p9PAWMmYYUjy9vimRfKRBJVe1S66d1UpVUVdtUNW4giEJ2VaPWcaIeY8M+x2EUEheqRCkAAACA0lX0bdCpAXdVnfMLansq7H2D2vPpqFy3QZds2TJpVy6sjaF02+iSsDaXdFOaTS+YCp6Wbm0x+w8fddr/UiClbZiqXaJM22gqlGTtbiVbLlW5vPvljc76B9GNvzrJCBP2vh35XHWUty039c6YKoDztyeW789osrYLFcipt9ig9rrCPteZtkGXbhtyYe38KQxNpxfYdOSjDTr/+hXqmMxmXfJB++6V2LG2cXfsc7Brf+CyeenYU2k8r0zPb9kcMyrNqk4tgvjfK9PPAgAAAIDcKOoSdAoDgsI5OWZQTzvUJqxkQzGVTMqXYwO2h6h6X7rrv3JH8LYenGGJET/dHKqql27ktT/dmz8FPclsD6nKmmkJlmKhMPLCcbV2rD3dfCerDlfXO3i9s+nJNFNutV0FtgoT9acQLqwqrL89sXx/RsPaJ1SQo4CkWAKGsNKIq5tS95isNvUUoqjnUAVkCnp0roxCMRyTUdBxrFBM4aB+LFHIpaAs7PhuzkE162yOmUyOj7B2/YqthDUAAABQboo6oAv7xV9OG1Fjh9rUh1R5XbCu/AM63RiG3Rym0xaYGjMPa6vrjJF97FDH1PcJbitwcZL2BSXs8YE9u9ih0qObepVIDJOsOtyJIR2KKPRMVZItXXrvPy3e5gQ/Kr2qUjsKgsLomFNgl2ydvPL9GQ0LQlK1V7mlwO0ahm0HheTJ9qWCTH1OFXK/s6XFCb1VCkvt7YUdN/lUiGMyCtrOOm/qc6DjX4GogtFk9Nl+35j8BcBhx8w7W1uSbms9tnJH6hDPNbI2+LOi9wEAAACQP0Ub0OnGKLz0XHVg1chJselBFHokK6GjEEJ/CiT0vroxy1WJnkI6ZmDw+utmPlnIonWdHxKQaFuHBX/pmjokuHSflkthUBBND6pmJcmqxZaCKyYPSNqe299XBgct2g9hbaX96o3Ndqg9Hc+ff2yVEzKohJ7CWIU5/pt6PaawR72duqUd9RwFQak+D+mWmIrqM7oqSUChz0ZYteN8ObE+ONhS+HbvW+E9fz69KvjYUAnGKEoH5vuYjIKWTdWk9QORPgc6/nUucvZNil5Z81nKLOyY0bGb7JjRfsjk+FboGlQiVvsm2fprP7qlO/UZ1Tk8itAYAAAAKFWdvxZjh3Pm4XeDS2w19OluThgaXtJGX+ZfXNNsfv3mltDqlrpxuHbqIDMgoBrOqNoeTlVKtXXm99qGPU4pmV7dOrW+Vjdiv1+01WlHaO/BI2ZHyyGzLnaDpfbS9PwDsfn4q9Jq/kElzVKtW9g2uXRifzvUnkILLY+fwp3ZATfjdb27mRfXNpvDR9qvv3o+1fz2xNZzvA24FHD8bXmT+cvS7YGvSbatM6HOPPTeQdtthUoMefaLqmL9ZWm8SmwQrfunTxpqx9pT21na1v6/3rHX6fjIhbD9Isn2p6tXt86ma+cqs2hzcAlBHYvaJkHHk/ajtpmfjl2FrLoRd/evuy2fj32mNF3bX8f66p37nffW/j9vbFuV2z49Opt/xI6fIG9vaXFee+To0YTOWfQZenDJ9tAwXTf77vJIvj+jYZ9PvcY7b4UNOvYfWLwtaemiKUN6Bh43OqaChD3fT8ug/RjUI7GmqbRSj9jnz93W2le/Xbgl6Xb2Hy8dPVdJJuuXz2PSlc26ZErLGnaMajm1rvtiy+7dDlruvyjQC/mhY0y/Hu0Ctvea4uscJOg8omMm7DwadH7XZ0edz4T90OHyv5fOT9pPQcem1j/o2PzD21udddE20/Lp86btpGn6f3JD+xLvAAAAABIVtJOIXPA3Ou+nkC+s4e1MqGRIUIP9Kh0QdMOTqrHyjjSOr1IIQQ2wB3US4dJNWbKqwZlQD5cK6HIhV/slVUPl2Tben46w/SKZdHagEie6qQ4T1olG2DGYqaDG5VWaTCWGckFhalAHJfn8jKbappkKO25ycZwpBEnWaUi6FKR/dXZDu5KuHT1XSabrl89jUrJZl45Q6S+VJM2VoM9yss9B2HkkV58dr6D3UoD9jXmNOTk2P3NSXcmXegYAAAAKoajboPNTO1fJwjnRzaOqZWZDNxVzYjeKpShVG2fp0jbMVTgn2i8K/LKhcDbd8KMUpKrqev+i4Btx7WMdo9nQ/g0KQq49blC7oKejPjxloB1KlM/P6DkdbAMsbHsmqxqbLYUWZ2b5mRB1PJKrfdZR+Twmo6DrTLbHqEvnvVwFVPrsKJTsiEz2j46nXBybmgfhHAAAAJCekgjodGOhcEY9R6ZDvTV29OZK7/Wx4weZGSGNn5cCbadswjC3x8tcU+DX0ZvLVCUnS5Fugi+eEB5IqMRQUJtPOjZ1jHY0ENFnI2z/apk+N2toVoGP+3lN9hnK12dUYYDeOxNaV5XyCZLv3kh1TGe6vF56bTGEWvk8JqOSzTHq0o8lufyhQ1RiMNPl0vMHZdi5Ti6OzXI7ZwMAAAD5VPQBnW4sdPOc6Rd93VzpBiGTG0ZVHdV7lXI459JNoapVje2ffrtrWn9VYctHlTGX5q1qbMlKjnnpeVqmcr3RU4mYZCUe1aZVUMP5OkZ1rGayf/VZUHCbKghRYKWqowpTMw1cdAwpqElnf+XrM+oGC+nMV9tegaSCPc3brxC9kWp5b54xJPD9wxTj5yKfx2RUtFyZnK9cer5el+6PSpnScmm7pXOMZ/ODi44vHWeZBPblfs4GAAAA8qWgnUSkopuNob27mvrYjer0ob3NDScMNueMqW1tMD5TajxepUvUkHy3LlWmqqrKaWje5b6fGvC+bGL/2E1F6g4ROtpYedg2yWUnEX5al9NG9DETBlabrp2qzOGjR51GvL0dQigU0PqfNbqv+di0wWk1cJ8tNWKuhuDD9otuBkfWdneWXR1CZLJM2Tben46w/SLpdBLhp3VVQ+tBjdJrX63Zud/ZFn7e/atdWhWb5t+/2pZDa7qZmcN6m48eP8icPDz9Eow6ntX5gI4d7Sc1DO8/9nUs6j30Wbs49lnTZ8jbiUQq+fiMiuaroMjdLt7l1vIqkFOIfcG4fk6j+LJix/7A/arl8X+2c32caZvpM63OTLrEtrf+/Nva+1m9eUZdyvcpVCcRXvk6JgvZSYSfe77qHNsn1bHjUfvGv07e41SBmM5bbmcNYTLtJMLvuCG9nGO8JXZ86tTh/dzoWFH4fMWxA8y5sWuohG3DVO+l/X1O7JhLdWzqut2RczYAAACAuLx0EgEAAAAAAAAgPZnVXwMAAAAAAACQUwR0AAAAAAAAQIQI6AAAAAAAAIAIEdABAAAAAAAAESKgAwAAAAAAACJEQAcAAAAAAABEiIAOAAAAAAAAiBABHQAAAAAAABAhAjoAAAAAAAAgQgR0AAAAAAAAQIQI6AAAAAAAAIAIEdABAAAAAAAAESKgAwAAAAAAACJEQAcAAAAAAABEiIAOAAAAAAAAiBABHQAAAAAAABAhAjoAAAAAAAAgQgR0AAAAAAAAQIQI6AAAAAAAAIAIEdABAAAAAAAAESKgAwAAAAAAACJEQAcAAAAAAABEiIAOAAAAAAAAiBABHQAAAAAAABAhAjoAAAAAAAAgQgR0AAAAAAAAQIQI6AAAAAAAAIAIEdABAAAAAAAAESKgAwAAAAAAACJEQAcAAAAAAABEiIAOAAAAAAAAiBABHQAAAAAAABAhAjoAAAAAAAAgQgR0AAAAAAAAQISqjsbY4aLU3NxshwAAAAAEqampsUNAZeA+EUBU8nXNpQQdAAAAAAAAECECOgAAAAAAACBCBHQAAAAAAABAhAjoAAAAAAAAgAgR0AEAAAAAAAARIqADAAAAAAAAIkRABwAAAAAAAESIgA4AAAAAAACIEAEdAAAAAAAAECECOgAAAAAAACBCBHQAAAAAAABAhAjoAAAAAAAAgAgR0AEAAAAAAAARIqADAAAAAAAAIkRABwAAAAAAAESIgA4AAAAAAACIEAEdAAAAAAAAECECOgAAAAAAACBCBHQAAAAAAABAhAjoAAAAAAAAgAgR0AEAAAAAAAARIqADAAAAAAAAIlR1NMYOF6Xm5mY7BAAAACBITU2NHQIqQyHuExesO2SHAJSDmfVd7FB28nXNJaADACAFvqAD5SVXX9CLCQEdKg0BHYBMEdBlqRwCOk7sAEpBOd6w5grncaC8ENABpY+ADkCmij2gow06AAAAAAAAIEIEdAAAAAAAAECECOgAAAAAAACACBHQAQAAAAAAABEioAMAAAAAAAAiREAHAAAAAAAARIiADgAAAAAAAIgQAR0AAAAAAAAQIQI6AAAAAAAAIEIEdAAAAAAAAECECOgAAAAAAACACBHQAQAAAAAAABEioAMAAAAAAAAiREAHAAAAAAAARIiADgAAAAAAAIgQAR0AAAAAAAAQIQI6AAAAAAAAIEIEdAAAAAAAAECECOgAAAAAAACACFUdjbHDRam5udkOla4F6w7ZIQAoXjPru9gh+EVxHn/11bfMggULzbrGjWbduk12qjH9+teahoYhZsqxE82ME48z/fv3tY+g0NasWWeeeWa+Wb9uo1m27D071Zge1T3M8IY6c+yUCWbatGPMiBH19hEUi3I839XU1NghoDIU4j6x2O7j9N3g7h/+2o6lpu8MAwfUOtej00+fyXeGIvEfd/wo4XvDZz77UTNjxnF2DPmUq+t/vq65BHQFUCoBnW40vvZ/vmfH4nST8Y1vfDFnJ3P/RWX8+FHmn7/yaTtWOMW6HMloGfvF9sPMmVMLegJ/8onnzYqVq80tt3zETsmdT3z8djsU98v/vtMOIQoEdOEKeR7fvn2n+cmPf5vwxS2MvnjfeNOHzORjxtspKJR77vmTeXbuS3YsnK6jH5xzvjnv/NPtFBQDAjqg9BHQZYbvDMWDgC46xR7QUcUVrVQKwG9fyz7z6itv2TFESSfxl+e/6VyUv/vdXzg38fmkYO6LX7zD/O53fzE78vxeANp8966fpxXOyY7tTeaHP/i1WfzOMjsFhZBuOCe6juo8qnMqAABR0XeGX/z8D3YMQDEioEOr+fPfsEOJXnlloR1CsXhr4VLnJj5fIZ1+nYsHc012CoBC+MtfnkqozpoOBUAP/flJO4Z8Uxiabjjn9ecHn8j7DysAACSj7/b8YAQULwI6OJ5/boFzkxdEJTlU/bWcqAixqlO6f1FUb82WbuLvueePdgxAOXh70bt2KE5V2z/xiQ8lnK++dPvN5ripE+0z4nSephRdYSx6K3EfqcrQNde833z7O//Suo++9n8/by686Ez7jDhdY59/foEdAwAge/qe4P2O4P3TdWnOB893mlrwWvT2UjsEoNjQBl0BlEIbdKoyqVJZLt38ecd1o3HVVZfYsY4rlrbfikW620PPW7QouNRGPtosKNR+og264kIbdOEKdR73fyb05TqsDdB//ep3EkrbJTsX6DM9b97LZtmy1a0/xtTXD4md6yeZc889PWU7o25nCMuXrUp4T81j3PjR5uyzZwV2hJBuGyupzgXex3U++sAHzzN/e3xe63VKy3HBBbPN6WfMdMZFpdWeeur52HOWtC6zblLGjx9pZs8+qcPnTf86KUD1vq+XvypssmuptvGjj8519pFbelnhn5b34ovPCu1owr88Ombuv/9hszC2bbSv3XmoiQSXttfXv/FFO5ZIP9j98pdtVaD0feALX7jRjrXp6DHVkX2ZD7RBB5Q+2qBL7zu6/1qU7DUdvRaJ+9pknVulao8122u3e21qbNyUUBPIXYewtrz921XX62FDB5u//W1e63LoenjBhbMT2vDL5fej0aNHtFt3zWf27Fl522733/+IefyxZ+1YfDlWrFhj5se+M2j7aR5TY+t91VWXtl7Xw7axlrW+oa7g7aVnqtjboCOgK4BiD+j0gf7SF79px+InH32QvScpndS+852v2LHk9OV+wSsLW79suydEfbBXrVqT9KISdHLUF/1UJyv3pOSeTETzPiP2BT/oS346Fzf/TYQed09I3hsSd3t15ESUznJ4qYTMt+/8mR2LO2nW8YEdOLjbZMXy1QkXANH7BPXm5F+eIP5lDLsYuxeFZBfjoJtyraNu1txt7F4YZp95UtJGbTuyvl7F8KUiagR04Qp1Hle7j94vOzq/XHHFhVn1AvrjH/82IZzx0zF67TWXhQYiqgqj6pnuOS+MSpH5PyP5COh0/hfv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",
+      "text/plain": [
+       "<IPython.core.display.Image object>"
+      ]
+     },
+     "execution_count": 1,
+     "metadata": {
+      "image/png": {
+       "width": 800
+      }
+     },
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "from IPython.display import Image\n",
+    "Image(filename=\"images/image_demo_client.png\", width=800)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "5b73135c",
+   "metadata": {},
+   "source": [
+    "🐧🐧🐧\n",
+    "In this notebook the researcher is a penguin researcher named Dr. Antarctica. She aims to do a grounbdbreaking research on various penguins dimensions.\n",
+    "\n",
+    "Therefore, the powerful queen Icerbegina 👑 had the data collected. But in order to get the penguins to agree to participate she promised them that no one would be able to look at the data and that no one would be able to guess the bill width of any specific penguin (which is very sensitive information) from the data. Nobody! Not even the researchers. The queen hence stored the data on the Secure Data Disclosure Server and only gave a small budget to Dr. Antarctica.\n",
+    "\n",
+    "This is not a problem for Dr. Antarctica as she does not need to see the data to make statistics thanks to the Secure Data Disclosure Client library `lomas-client`. \n",
+    "🐧🐧🐧"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "01ae30d2",
+   "metadata": {},
+   "source": [
+    "## Step 1: Install the library\n",
+    "To interact with the secure server on which the data is stored, Dr.Antartica first needs to install the library `lomas-client` on her local developping environment. \n",
+    "\n",
+    "It can be installed via the pip command:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "id": "28fbdd79-8c15-49a9-bcf9-fcdeac09d2b5",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#!pip install lomas-client"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "id": "6fb569fc",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from lomas_client import Client\n",
+    "import numpy as np"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "9c63718b",
+   "metadata": {},
+   "source": [
+    "## Step 2: Initialise the client\n",
+    "\n",
+    "Once the library is installed, a Client object must be created. It is responsible for sending sending requests to the server and processing responses in the local environment. It enables a seamless interaction with the server. \n",
+    "\n",
+    "To create the client, Dr. Antartica needs to give it a few parameters:\n",
+    "- a url: the root application endpoint to the remote secure server.\n",
+    "- user_name: her name as registered in the database (Dr. Alice Antartica)\n",
+    "- dataset_name: the name of the dataset that she wants to query (PENGUIN)\n",
+    "\n",
+    "She will only be able to query on the real dataset if the queen Icergina has previously made her an account in the database, given her access to the PENGUIN dataset and has given her some epsilon and delta credit (as is done in the Admin Notebook for Users and Datasets management)."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "id": "941991f7",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "APP_URL = \"http://lomas_server_dev:80\"\n",
+    "# APP_URL = \"https://lomas-server.lab.sspcloud.fr\"\n",
+    "USER_NAME = \"Dr. Antartica\"\n",
+    "DATASET_NAME = \"PENGUIN\"\n",
+    "client = Client(url=APP_URL, user_name = USER_NAME, dataset_name = DATASET_NAME)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "0ec400c8",
+   "metadata": {},
+   "source": [
+    "And that's it for the preparation. She is now ready to use the various functionnalities offered by `lomas_client`."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "9b9a5f13",
+   "metadata": {},
+   "source": [
+    "## Step 3: Understand the functionnalities of the library"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "c7cb5531",
+   "metadata": {},
+   "source": [
+    "### Getting dataset metadata\n",
+    "\n",
+    "Dr. Antartica has never seen the data and as a first step to understand what is available to her, she would like to check the metadata of the dataset. Therefore, she just needs to call the `get_dataset_metadata()` function of the client. As this is public information, this does not cost any budget.\n",
+    "\n",
+    "This function returns metadata information in a format based on [SmartnoiseSQL dictionary format](https://docs.smartnoise.org/sql/metadata.html#dictionary-format), where among other, there is information about all the available columns, their type, bound values (see Smartnoise page for more details). Any metadata is required for Smartnoise-SQL is also required here and additional information such that the different categories in a string type column column can be added."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "id": "0fdebac9-57fc-4410-878b-5a77425af634",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'max_ids': 1,\n",
+       " 'row_privacy': True,\n",
+       " 'censor_dims': False,\n",
+       " 'species': {'type': 'string',\n",
+       "  'cardinality': 3,\n",
+       "  'categories': ['Adelie', 'Chinstrap', 'Gentoo']},\n",
+       " 'island': {'type': 'string',\n",
+       "  'cardinality': 3,\n",
+       "  'categories': ['Torgersen', 'Biscoe', 'Dream']},\n",
+       " 'bill_length_mm': {'type': 'float', 'lower': 30.0, 'upper': 65.0},\n",
+       " 'bill_depth_mm': {'type': 'float', 'lower': 13.0, 'upper': 23.0},\n",
+       " 'flipper_length_mm': {'type': 'float', 'lower': 150.0, 'upper': 250.0},\n",
+       " 'body_mass_g': {'type': 'float', 'lower': 2000.0, 'upper': 7000.0},\n",
+       " 'sex': {'type': 'string', 'cardinality': 2, 'categories': ['MALE', 'FEMALE']}}"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "penguin_metadata = client.get_dataset_metadata()\n",
+    "penguin_metadata"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "d338ed96",
+   "metadata": {},
+   "source": [
+    "Based on this Dr. Antartica knows that there are 7 columns, 3 of string type (species, island, sex) with their associated categories (i.e. the species column has 3 possibilities: 'Adelie', 'Chinstrap', 'Gentoo') and 4 of float type (bill length, bill depth, flipper length and body mass) with their associated bounds (i.e. the body mass of penguin ranges from 2000 to 7000 gramms). She also knows based on the field `max_ids: 1` that each penguin can only be once in the dataset and on the field `row_privacy: True` that each row represents a single penguin. "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "5a3c899d",
+   "metadata": {},
+   "source": [
+    "### Get a dummy dataset\n",
+    "\n",
+    "Now, that she has seen and understood the metadata, she wants to get an even better understanding of the dataset (but is still not able to see it). A solution to have an idea of what the dataset looks like it to create a dummy dataset. \n",
+    "\n",
+    "Based on the public metadata of the dataset, a random dataframe can be created created. By default, there will be 100 rows and the seed is set to 42 to ensure reproducibility, but these 2 variables can be changed to obtain different dummy datasets.\n",
+    "Getting a dummy dataset does not affect the budget as there is no differential privacy here. It is not a synthetic dataset and all that could be learn here is already present in the public metadata (it is created randomly on the fly based on the metadata).\n",
+    "\n",
+    "Dr. Antartica first create a dummy dataset with 200 rows and chooses a seed of 0."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "id": "01f4365a",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "NB_ROWS = 200\n",
+    "SEED = 0"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "id": "3f553b29",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "(200, 7)\n"
+     ]
     },
-    "nbformat": 4,
-    "nbformat_minor": 5
+    {
+     "data": {
+      "text/html": [
+       "<div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>species</th>\n",
+       "      <th>island</th>\n",
+       "      <th>bill_length_mm</th>\n",
+       "      <th>bill_depth_mm</th>\n",
+       "      <th>flipper_length_mm</th>\n",
+       "      <th>body_mass_g</th>\n",
+       "      <th>sex</th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>Gentoo</td>\n",
+       "      <td>Biscoe</td>\n",
+       "      <td>49.208473</td>\n",
+       "      <td>16.117959</td>\n",
+       "      <td>190.125950</td>\n",
+       "      <td>2873.291927</td>\n",
+       "      <td>FEMALE</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>Gentoo</td>\n",
+       "      <td>Torgersen</td>\n",
+       "      <td>55.031628</td>\n",
+       "      <td>19.963435</td>\n",
+       "      <td>242.929142</td>\n",
+       "      <td>3639.940005</td>\n",
+       "      <td>FEMALE</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>Chinstrap</td>\n",
+       "      <td>Torgersen</td>\n",
+       "      <td>51.096718</td>\n",
+       "      <td>16.777518</td>\n",
+       "      <td>159.961493</td>\n",
+       "      <td>5401.743330</td>\n",
+       "      <td>MALE</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>Adelie</td>\n",
+       "      <td>Biscoe</td>\n",
+       "      <td>49.070911</td>\n",
+       "      <td>14.796037</td>\n",
+       "      <td>244.530153</td>\n",
+       "      <td>2316.038092</td>\n",
+       "      <td>MALE</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>Chinstrap</td>\n",
+       "      <td>Biscoe</td>\n",
+       "      <td>44.827918</td>\n",
+       "      <td>13.246787</td>\n",
+       "      <td>236.948853</td>\n",
+       "      <td>5036.246870</td>\n",
+       "      <td>FEMALE</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "     species     island  bill_length_mm  bill_depth_mm  flipper_length_mm   \n",
+       "0     Gentoo     Biscoe       49.208473      16.117959         190.125950  \\\n",
+       "1     Gentoo  Torgersen       55.031628      19.963435         242.929142   \n",
+       "2  Chinstrap  Torgersen       51.096718      16.777518         159.961493   \n",
+       "3     Adelie     Biscoe       49.070911      14.796037         244.530153   \n",
+       "4  Chinstrap     Biscoe       44.827918      13.246787         236.948853   \n",
+       "\n",
+       "   body_mass_g     sex  \n",
+       "0  2873.291927  FEMALE  \n",
+       "1  3639.940005  FEMALE  \n",
+       "2  5401.743330    MALE  \n",
+       "3  2316.038092    MALE  \n",
+       "4  5036.246870  FEMALE  "
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "df_dummy = client.get_dummy_dataset(\n",
+    "    nb_rows = NB_ROWS, \n",
+    "    seed = SEED\n",
+    ")\n",
+    "\n",
+    "print(df_dummy.shape)\n",
+    "df_dummy.head()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "98e6fda2-dde7-4f8b-a787-c9a1e3571ebe",
+   "metadata": {},
+   "source": [
+    "### Query on dummy dataset\n",
+    "Now that she has an idea of what the data looks like, she wants to start querying the real dataset for her research. \n",
+    "\n",
+    "However, her budget is limited and it would be a waste to spend it by mistake on a coding error. Therefore the client/server pipeline has functionnal testing capabilities for the users. It is possible to test a query on a `dummy` dataset to ensure that everything is working properly. Dr. Antartica will not be able to use the results of a dummy query for her analysis (as the data is random) but if the query on the dummy dataset works, she can be confident that her query will also work on the real dataset.\n",
+    "This functionnal testing on the dummy does not have any impact on the budget as it is on random data only.\n",
+    "\n",
+    "To test on the dummy data instead of the real data, the function call is exactly the same with the only exception of the flag `dummy=True`. In the following cell, she will test with `smartnoise_query` but it is the same flag for `opendp_query`. She can optionnaly give two additional parameters to set the seed and the number of rows of the dummy dataset.\n",
+    "\n",
+    "Another more advanced possibility for functionnal tests with the dummy is to compare results of queries on a local dummy and the remote dummy with a very high budget: \n",
+    "- create a local dummy on the notebook with a specific seed and number of rows\n",
+    "- compute locally the wanted query on this local dummy with python functions like numpy\n",
+    "- query the server on the same remote dummy with (`dummy=True`, same seed and same number of row) and a very big buget to limit noise as much as possible (don't worry this won't cost any real budget)\n",
+    "- compare and verify that the local and remote dummy have similar results."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "243c73e3-daec-45d6-a3c8-ae1d60439ec4",
+   "metadata": {},
+   "source": [
+    "#### Average and number of rows with smartnoise-sql library on remote dummy"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "d1f8ea18-ccab-4f75-9490-b4d1144b39db",
+   "metadata": {},
+   "source": [
+    "Dr. Antartica will now try a query to get the number of penguin and their average bill length (in mm) on the dummy dataset. She does not forget to \n",
+    "- set the `dummy` flag to True\n",
+    "- set very high budget values to be able to compare results with a similar local dummy (with the same seed and number of rows) if she wants to verify that the function do what is expected. Here she will just check that the number of rows is close to what she sets as parameter."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "id": "3946425d",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Number of penguin and average bill length in mm\n",
+    "QUERY = \"SELECT COUNT(*) AS nb_penguins, \\\n",
+    "        AVG(bill_length_mm) AS avg_bill_length_mm \\\n",
+    "        FROM Schema.Table\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "id": "90cf2a6d",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# On the remote server dummy dataframe\n",
+    "dummy_res = client.smartnoise_query(\n",
+    "    query = QUERY,  \n",
+    "    epsilon = 100.0,\n",
+    "    delta = 0.99,\n",
+    "    dummy = True, \n",
+    "    nb_rows = NB_ROWS,\n",
+    "    seed = SEED\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "id": "a30f277e",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Average bill length in remote dummy: 47.51mm.\n",
+      "Number of rows in remote dummy: 200.\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(f\"Average bill length in remote dummy: {np.round(dummy_res['query_response']['avg_bill_length_mm'][0], 2)}mm.\")\n",
+    "print(f\"Number of rows in remote dummy: {np.round(dummy_res['query_response']['nb_penguins'][0], 2)}.\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "167e8c6d-6c93-4ab4-9ba7-bf7e783a6bc2",
+   "metadata": {},
+   "source": [
+    "No functionnal errors happened and the estimated number of rows is very close (if not equal) to the number of rows that she set for the dummy dataframe. She is now even more confident in using her query on the server."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "324454ed",
+   "metadata": {},
+   "source": [
+    "### Get current budget\n",
+    "\n",
+    "It is the first time that Dr. Antartica connects to the server and she wants to know how much buget the queen assigned her.\n",
+    "Therefore, she calls the fonction `get_initial_budget`."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "id": "61a467f3",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'initial_epsilon': 10, 'initial_delta': 0.005}"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "client.get_initial_budget()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "bc8f7a74",
+   "metadata": {},
+   "source": [
+    "She sees that she has 10.0 epsilon and 0.005 epsilon at her disposal.\n",
+    "\n",
+    "Then she checks her total spent budget `get_total_spent_budget`. As she only did queries on metadata on dummy dataframes, this should still be 0."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "id": "afd22f84",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'total_spent_epsilon': 0, 'total_spent_delta': 0}"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "client.get_total_spent_budget()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "05daf5a4",
+   "metadata": {},
+   "source": [
+    "It will also be useful to know what the remaining budget is. Therefore, she calls the function `get_remaining_budget`. It just substarcts the total spent budget from the initial budget."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "id": "6260cf54",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'remaining_epsilon': 10, 'remaining_delta': 0.005}"
+      ]
+     },
+     "execution_count": 13,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "client.get_remaining_budget()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "20298e00",
+   "metadata": {},
+   "source": [
+    "As expected, for now the remaining budget is equal to the inital budget."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "b746374c",
+   "metadata": {},
+   "source": [
+    "### Estimate cost of a query\n",
+    "Another safeguard is the functionnality to estimate the cost of a query. As in OpenDP and SmartnoiseSQL, the budget that will by used by a query might be slightly different than what is asked by the user. The `estimate cost` function returns the estimated real cost of any query.\n",
+    "\n",
+    "Again, of course, this will not impact the user's budget.\n",
+    "\n",
+    "Dr. Antartica checks the budget that computing the average bill length will really cost her if she asks the query with an `epsilon` and a `delta`."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "id": "fd5ed08a",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "EPSILON = 0.5\n",
+    "DELTA = 1e-4"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "id": "133020c6",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'epsilon_cost': 1.5, 'delta_cost': 0.00014999500000001387}"
+      ]
+     },
+     "execution_count": 15,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "client.estimate_smartnoise_cost(\n",
+    "    query = QUERY, \n",
+    "    epsilon = EPSILON, \n",
+    "    delta = DELTA\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "3c6a3a8c",
+   "metadata": {},
+   "source": [
+    "This query would actually cost her 1.5 epsilon and delta 1.4999e-4. She decides that it is good enough."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "e5379edf",
+   "metadata": {},
+   "source": [
+    "### Query on real private dataset with smartnoise-sql\n",
+    "Now that all the safeguard functions were tested, Dr. Antartica is ready to query on the real dataset and get a differentially private response of the number of penguins and average bill length. By default, the flag `dummy` is False so setting it is optional. She uses the values of `epsilon` and `delta` that she selected just before.\n",
+    "\n",
+    "Careful: This command DOES spend the budget of the user and the remaining budget is updated for every query."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "id": "19e60263",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'remaining_epsilon': 10, 'remaining_delta': 0.005}"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "client.get_remaining_budget()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "id": "69767fac",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "response = client.smartnoise_query(\n",
+    "    query = QUERY,  \n",
+    "    epsilon = EPSILON, \n",
+    "    delta = DELTA,\n",
+    "    dummy = False # Optionnal\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "id": "6dbbdf93",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Number of penguins in real data: 344.\n",
+      "Average bill length of penguins in real data: 43.54mm.\n"
+     ]
+    }
+   ],
+   "source": [
+    "nb_penguins = response['query_response']['nb_penguins'].iloc[0]\n",
+    "print(f\"Number of penguins in real data: {nb_penguins}.\")\n",
+    "\n",
+    "avg_bill_length = np.round(response['query_response']['avg_bill_length_mm'].iloc[0], 2)\n",
+    "print(f\"Average bill length of penguins in real data: {avg_bill_length}mm.\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "b2767e65",
+   "metadata": {},
+   "source": [
+    "After each query on the real dataset, the budget informations are also returned to the researcher. It is possible possible to check the remaining budget again afterwards:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "id": "4ced8a56-e2c3-4bd1-b94b-95cbbcd58a15",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'requested_by': 'Dr. Antartica',\n",
+       " 'query_response':    nb_penguins  avg_bill_length_mm\n",
+       " 0          344           43.537797,\n",
+       " 'spent_epsilon': 1.5,\n",
+       " 'spent_delta': 0.00014999500000001387}"
+      ]
+     },
+     "execution_count": 19,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "response"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "id": "39701fe5",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'remaining_epsilon': 8.5, 'remaining_delta': 0.004850004999999986}"
+      ]
+     },
+     "execution_count": 20,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "client.get_remaining_budget()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "e37c587f",
+   "metadata": {},
+   "source": [
+    "As can be seen in `get_total_spent_budget()`, it is the budget estimated with `estimate_smartnoise_cost()` that was spent."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "id": "487f835f",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'total_spent_epsilon': 1.5, 'total_spent_delta': 0.00014999500000001387}"
+      ]
+     },
+     "execution_count": 21,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "client.get_total_spent_budget()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "eef4afcd",
+   "metadata": {},
+   "source": [
+    "Dr. Antartica has now a differentially private estimation of the number of penguins in the dataset and is confident to use the library for the rest of her analyses."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "04929993",
+   "metadata": {},
+   "source": [
+    "## Step 4: Penguin statistics with opendp"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "id": "b9685226",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import opendp as dp\n",
+    "import opendp.transformations as trans\n",
+    "import opendp.measurements as meas"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "bbbca191",
+   "metadata": {},
+   "source": [
+    "### Confidence intervals for bill length over the whole population"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "9d41bd58",
+   "metadata": {},
+   "source": [
+    "She is first interested to have a better idea of the distribution of bill length of all species. She already has the count and average from the previous step, so she only needs the variance values.\n",
+    "\n",
+    "She first checks the metadata again to use the relevant values in the pipeline."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "id": "4331d86f",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'max_ids': 1,\n",
+       " 'row_privacy': True,\n",
+       " 'censor_dims': False,\n",
+       " 'species': {'type': 'string',\n",
+       "  'cardinality': 3,\n",
+       "  'categories': ['Adelie', 'Chinstrap', 'Gentoo']},\n",
+       " 'island': {'type': 'string',\n",
+       "  'cardinality': 3,\n",
+       "  'categories': ['Torgersen', 'Biscoe', 'Dream']},\n",
+       " 'bill_length_mm': {'type': 'float', 'lower': 30.0, 'upper': 65.0},\n",
+       " 'bill_depth_mm': {'type': 'float', 'lower': 13.0, 'upper': 23.0},\n",
+       " 'flipper_length_mm': {'type': 'float', 'lower': 150.0, 'upper': 250.0},\n",
+       " 'body_mass_g': {'type': 'float', 'lower': 2000.0, 'upper': 7000.0},\n",
+       " 'sex': {'type': 'string', 'cardinality': 2, 'categories': ['MALE', 'FEMALE']}}"
+      ]
+     },
+     "execution_count": 23,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "penguin_metadata"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "f90e0425",
+   "metadata": {},
+   "source": [
+    "She can define the columns names and the bounds of the relevant column."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "id": "ff8cb7b6",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "columns = [\"species\", \"island\", \"bill_length_mm\", \"bill_depth_mm\", \"flipper_length_mm\", \"body_mass_g\", \"sex\"]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "id": "70b2bdb1",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(30.0, 65.0)"
+      ]
+     },
+     "execution_count": 25,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "bill_length_min = penguin_metadata['bill_length_mm']['lower']\n",
+    "bill_length_max = penguin_metadata['bill_length_mm']['upper']\n",
+    "bill_length_min, bill_length_max"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "e93ae087",
+   "metadata": {},
+   "source": [
+    "She can now define the pipeline of the transformation to have the variance that she wants on the data:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "id": "75e4933b",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "bill_length_transformation_pipeline = (\n",
+    "    trans.make_split_dataframe(separator=\",\", col_names=columns) >>\n",
+    "    trans.make_select_column(key=\"bill_length_mm\", TOA=str) >>\n",
+    "    trans.then_cast_default(TOA=float) >>\n",
+    "    trans.then_clamp(bounds=(bill_length_min, bill_length_max)) >>\n",
+    "    trans.then_resize(size=nb_penguins.tolist(), constant=avg_bill_length) >>\n",
+    "    trans.then_variance()\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "411d464c",
+   "metadata": {},
+   "source": [
+    "However, when she tries to execute it on the server, she has an error (see below). "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "id": "8041a647",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Server error status 400: {\"InvalidQueryException\":\"The pipeline provided is not a measurement. It cannot be processed in this server.\"}\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Expect to fail !!!\n",
+    "client.opendp_query(\n",
+    "    opendp_pipeline = bill_length_transformation_pipeline,\n",
+    "    dummy=True\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "d06c59dc",
+   "metadata": {},
+   "source": [
+    "This is because the server will only allow measurement pipeline with differentially private results. She adds Laplacian noise to the pipeline and should be able to instantiate the pipeline."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "id": "b8162859",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "var_bill_length_measurement_pipeline = (\n",
+    "    bill_length_transformation_pipeline >>\n",
+    "    meas.then_laplace(scale=5.0)\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "fc7e0ecd",
+   "metadata": {},
+   "source": [
+    "Now that there is a measurement, she is able to apply the pipeline on the dummy dataset of the server."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "id": "df61bce0",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Dummy result for variance: 40.04\n"
+     ]
+    }
+   ],
+   "source": [
+    "dummy_var_res = client.opendp_query(\n",
+    "    opendp_pipeline = var_bill_length_measurement_pipeline, \n",
+    "    dummy=True\n",
+    ")\n",
+    "print(f\"Dummy result for variance: {np.round(dummy_var_res['query_response'], 2)}\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "ded11ac4",
+   "metadata": {},
+   "source": [
+    "With opendp, the function `estimate_opendp_cost` is particularly useful to estimate the used `epsilon` and `delta` based on the `scale` value."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "id": "7ae7f735",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'epsilon_cost': 0.7122093023265229, 'delta_cost': 0}"
+      ]
+     },
+     "execution_count": 30,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "cost_res = client.estimate_opendp_cost(\n",
+    "    opendp_pipeline = var_bill_length_measurement_pipeline\n",
+    ")\n",
+    "cost_res"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "1c791d36",
+   "metadata": {},
+   "source": [
+    "She can now execute the query on the real dataset."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "id": "085555a5",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "var_res = client.opendp_query(\n",
+    "    opendp_pipeline = var_bill_length_measurement_pipeline, \n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 32,
+   "id": "674332e7",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Number of penguins: 344 (from previous smartnoise-sql query).\n",
+      "Average bill length: 43.54 (from previous smartnoise-sql query).\n",
+      "Variance of bill length: 31.24 (from opendp query).\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(f\"Number of penguins: {nb_penguins} (from previous smartnoise-sql query).\")\n",
+    "\n",
+    "print(f\"Average bill length: {np.round(avg_bill_length, 2)} (from previous smartnoise-sql query).\")\n",
+    "\n",
+    "var_bill_length = var_res['query_response']\n",
+    "print(f\"Variance of bill length: {np.round(var_bill_length, 3)} (from opendp query).\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "367081be-1159-45d8-9129-88fba20fb697",
+   "metadata": {},
+   "source": [
+    "She can now do all the postprocessing that she wants with the returned data without adding any privacy risk. "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "id": "f72b19d0",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Standard error of bill length: 0.3.\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Get standard error\n",
+    "standard_error = np.sqrt(var_bill_length/nb_penguins)\n",
+    "print(f\"Standard error of bill length: {np.round(standard_error, 2)}.\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "id": "62630a03",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The 95% confidence interval of the bill length of all penguins is [42.95, 44.13].\n"
+     ]
+    }
+   ],
+   "source": [
+    " # Compute the 95% confidence interval\n",
+    "ZSCORE = 1.96\n",
+    "lower_bound = np.round(avg_bill_length - ZSCORE*standard_error, 2)\n",
+    "upper_bound = np.round(avg_bill_length + ZSCORE*standard_error, 2)\n",
+    "print(f\"The 95% confidence interval of the bill length of all penguins is [{lower_bound}, {upper_bound}].\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "0d30d98e-26f4-44ec-a0f0-7a039f344860",
+   "metadata": {},
+   "source": [
+    "### Count per species"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "b6a3cc00-8734-4479-81a3-781c91b8eb06",
+   "metadata": {},
+   "source": [
+    "She can also creates an histogram of the number of penguin per species.\n",
+    "\n",
+    "She first extract the categories from the metadata:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "id": "558916a6-78a9-4589-abe8-41472f0c66d7",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['Adelie', 'Chinstrap', 'Gentoo']"
+      ]
+     },
+     "execution_count": 35,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "categories = penguin_metadata['species']['categories']\n",
+    "categories"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "5f05aeb0-42d1-4444-a458-d2989494f544",
+   "metadata": {},
+   "source": [
+    "Then, writes the pipeline:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 36,
+   "id": "505a2793-6750-4f2a-9a9d-09f3a4ae4099",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "species_count_pipeline = (\n",
+    "    trans.make_split_dataframe(separator=\",\", col_names=columns) >>\n",
+    "    trans.make_select_column(key=\"species\", TOA=str) >>\n",
+    "    trans.then_count_by_categories(categories=categories) >>\n",
+    "    meas.then_laplace(scale=0.5)\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "0f4109a9-c2f2-4365-bfa1-b5b2512919f9",
+   "metadata": {},
+   "source": [
+    "Verify it works on the dummy:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 37,
+   "id": "712b1c74-cac6-4b3f-9421-8d8ffa9debc7",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Dummy result for histogram: [38, 33, 29, 0]\n"
+     ]
+    }
+   ],
+   "source": [
+    "dummy_res = client.opendp_query(\n",
+    "    opendp_pipeline = species_count_pipeline, \n",
+    "    dummy=True\n",
+    ")\n",
+    "print(f\"Dummy result for histogram: {dummy_res['query_response']}\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "66de7794-9aae-41d1-ba98-6b234a05d6f8",
+   "metadata": {},
+   "source": [
+    "Checks the required cost:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 38,
+   "id": "3f942b1b-94bc-468e-8374-3034f2e6b8ce",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'epsilon_cost': 2.0, 'delta_cost': 0}"
+      ]
+     },
+     "execution_count": 38,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "cost_res = client.estimate_opendp_cost(\n",
+    "    opendp_pipeline = species_count_pipeline\n",
+    ")\n",
+    "cost_res"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "1adfe446-ff13-41f4-9f3c-9998e2ae0f00",
+   "metadata": {},
+   "source": [
+    "And finally apply the pipeline on the real dataset:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 39,
+   "id": "c6fe47b7-048e-404a-bedb-720e734b0c70",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "species_counts_res = client.opendp_query(\n",
+    "    opendp_pipeline = species_count_pipeline, \n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 40,
+   "id": "78d1aa05-2777-476b-9520-f9206399670d",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'requested_by': 'Dr. Antartica',\n",
+       " 'query_response': [153, 68, 124, 0],\n",
+       " 'spent_epsilon': 2.0,\n",
+       " 'spent_delta': 0}"
+      ]
+     },
+     "execution_count": 40,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "species_counts_res"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 41,
+   "id": "b8d5fd82-5ded-47ec-8135-f6870865055d",
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Species Adelie has 153 penguins.\n",
+      "Species Chinstrap has 68 penguins.\n",
+      "Species Gentoo has 124 penguins.\n",
+      "Species Unknown has 0 penguins.\n"
+     ]
+    }
+   ],
+   "source": [
+    "for i, count in enumerate(species_counts_res['query_response']):\n",
+    "    if i == len(categories):\n",
+    "        print(f\"Species Unknown has {count} penguins.\")\n",
+    "    else:\n",
+    "        print(f\"Species {categories[i]} has {count} penguins.\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "94eaf59b-c108-424c-8978-b1c86e141ccb",
+   "metadata": {},
+   "source": [
+    "## Step 5: See archives of queries"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "64003c53-de56-4bdc-a3c2-0c3e40031919",
+   "metadata": {},
+   "source": [
+    "She now wants to verify all the queries that she did on the real data. It is possible because an archive of all queries is kept in a secure database. With a function call she can see her queries, budget and associated responses."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 42,
+   "id": "008fd230-cdfd-4e03-91ce-5a60b06c106d",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[{'user_name': 'Dr. Antartica',\n",
+       "  'dataset_name': 'PENGUIN',\n",
+       "  'client_input': {'query_str': 'SELECT COUNT(*) AS nb_penguins,         AVG(bill_length_mm) AS avg_bill_length_mm         FROM Schema.Table',\n",
+       "   'dataset_name': 'PENGUIN',\n",
+       "   'epsilon': 0.5,\n",
+       "   'delta': 0.0001,\n",
+       "   'mechanisms': {},\n",
+       "   'postprocess': True},\n",
+       "  'response': {'requested_by': 'Dr. Antartica',\n",
+       "   'query_response': {'index': [0],\n",
+       "    'columns': ['nb_penguins', 'avg_bill_length_mm'],\n",
+       "    'data': [[344, 43.53779658933454]],\n",
+       "    'index_names': [None],\n",
+       "    'column_names': [None]},\n",
+       "   'spent_epsilon': 1.5,\n",
+       "   'spent_delta': 0.00014999500000001387},\n",
+       "  'timestamp': 1714148848.066639,\n",
+       "  'api': 'smartnoise_sql'},\n",
+       " {'user_name': 'Dr. Antartica',\n",
+       "  'dataset_name': 'PENGUIN',\n",
+       "  'client_input': {'dataset_name': 'PENGUIN',\n",
+       "   'opendp_json': <opendp.mod.Measurement at 0x7f37da26cb90>,\n",
+       "   'fixed_delta': None},\n",
+       "  'response': {'requested_by': 'Dr. Antartica',\n",
+       "   'query_response': 31.239812832348537,\n",
+       "   'spent_epsilon': 0.7122093023265229,\n",
+       "   'spent_delta': 0},\n",
+       "  'timestamp': 1714148852.7148623,\n",
+       "  'api': 'opendp'},\n",
+       " {'user_name': 'Dr. Antartica',\n",
+       "  'dataset_name': 'PENGUIN',\n",
+       "  'client_input': {'dataset_name': 'PENGUIN',\n",
+       "   'opendp_json': <opendp.mod.Measurement at 0x7f37da26c3b0>,\n",
+       "   'fixed_delta': None},\n",
+       "  'response': {'requested_by': 'Dr. Antartica',\n",
+       "   'query_response': [153, 68, 124, 0],\n",
+       "   'spent_epsilon': 2.0,\n",
+       "   'spent_delta': 0},\n",
+       "  'timestamp': 1714148855.6369317,\n",
+       "  'api': 'opendp'}]"
+      ]
+     },
+     "execution_count": 42,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "previous_queries = client.get_previous_queries()\n",
+    "previous_queries"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "fd5cafca-b0d7-4a41-8b02-2bca43776bab",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "6de93684-a669-4146-b59b-bf7c5e00080f",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3 (ipykernel)",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.11.9"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
 }
diff --git a/server/requirements.txt b/server/requirements.txt
index 35db17ac..59afa50a 100644
--- a/server/requirements.txt
+++ b/server/requirements.txt
@@ -1,6 +1,7 @@
 boto3
 # diffprivlib==0.5.2
 fastapi
+httpx
 numpy
 opendp==0.8.0
 opendp-logger==0.3.0
diff --git a/server/src/admin_database/mongodb_database.py b/server/src/admin_database/mongodb_database.py
index 1e4bafde..5e372f60 100644
--- a/server/src/admin_database/mongodb_database.py
+++ b/server/src/admin_database/mongodb_database.py
@@ -286,24 +286,15 @@ def save_query(
         to_archive = {
             "user_name": user_name,
             "dataset_name": query_json.dataset_name,
+            "client_input": query_json.dict(),
             "response": response,
             "timestamp": time.time(),
         }
         match query_json.__class__.__name__:
             case "SNSQLInp":
-                to_archive["api"] = DPLibraries.SMARTNOISE_SQL
-                to_archive["query"] = query_json.query_str
-                to_archive["epsilon_parameter"] = query_json.epsilon
-                to_archive["delta_parameter"] = query_json.delta
-                to_archive["mechanisms"] = query_json.mechanisms
-                to_archive["postprocess"] = query_json.postprocess
-
+                to_archive["dp_librairy"] = DPLibraries.SMARTNOISE_SQL
             case "OpenDPInp":
-                to_archive["api"] = DPLibraries.OPENDP
-                to_archive["query"] = query_json.opendp_json
-                to_archive["input_data_type"] = query_json.input_data_type
-                to_archive["fixed_delta"] = query_json.fixed_delta
-
+                to_archive["dp_librairy"] = DPLibraries.OPENDP
             case _:
                 raise InternalServerException(
                     f"Unknown query input: {query_json.__class__.__name__}"
diff --git a/server/src/app.py b/server/src/app.py
index 150d49c6..14d39b28 100644
--- a/server/src/app.py
+++ b/server/src/app.py
@@ -1,4 +1,4 @@
-from typing import Callable, Dict, List, Union
+from typing import Callable
 
 from admin_database.admin_database import AdminDatabase
 from admin_database.utils import database_factory
@@ -27,7 +27,7 @@
 from utils.example_inputs import (
     example_dummy_opendp,
     example_dummy_smartnoise_sql,
-    example_get_db_data,
+    example_get_admin_db_data,
     example_get_dummy_dataset,
     example_opendp,
     example_smartnoise_sql,
@@ -165,7 +165,7 @@ async def get_state(
     tags=["USER_METADATA"],
 )
 def get_dataset_metadata(
-    query_json: GetDbData = Body(example_get_db_data),
+    query_json: GetDbData = Body(example_get_admin_db_data),
 ) -> JSONResponse:
     try:
         ds_metadata = ADMIN_DATABASE.get_dataset_metadata(
@@ -350,7 +350,7 @@ def estimate_opendp_cost(
     tags=["USER_BUDGET"],
 )
 def get_initial_budget(
-    query_json: GetDbData = Body(example_get_db_data),
+    query_json: GetDbData = Body(example_get_admin_db_data),
     user_name: str = Header(None),
 ) -> JSONResponse:
     try:
@@ -372,7 +372,7 @@ def get_initial_budget(
     tags=["USER_BUDGET"],
 )
 def get_total_spent_budget(
-    query_json: GetDbData = Body(example_get_db_data),
+    query_json: GetDbData = Body(example_get_admin_db_data),
     user_name: str = Header(None),
 ) -> JSONResponse:
     try:
@@ -400,7 +400,7 @@ def get_total_spent_budget(
     tags=["USER_BUDGET"],
 )
 def get_remaining_budget(
-    query_json: GetDbData = Body(example_get_db_data),
+    query_json: GetDbData = Body(example_get_admin_db_data),
     user_name: str = Header(None),
 ) -> JSONResponse:
     try:
@@ -422,7 +422,7 @@ def get_remaining_budget(
     tags=["USER_BUDGET"],
 )
 def get_user_previous_queries(
-    query_json: GetDbData = Body(example_get_db_data),
+    query_json: GetDbData = Body(example_get_admin_db_data),
     user_name: str = Header(None),
 ) -> JSONResponse:
     try:
diff --git a/server/src/constants.py b/server/src/constants.py
index 59927f10..2d27ab03 100644
--- a/server/src/constants.py
+++ b/server/src/constants.py
@@ -39,7 +39,7 @@ class ConfDatasetStore(StrEnum):
 )
 
 # DP constants
-EPSILON_LIMIT: float = 10.0
+EPSILON_LIMIT: float = 5.0
 DELTA_LIMIT: float = 0.0004
 
 
@@ -49,12 +49,6 @@ class DPLibraries(StrEnum):
     OPENDP = "opendp"
 
 
-# OpenDP pipeline input types
-class OpenDPInputType(StrEnum):
-    DF = "df"
-    PATH = "path"
-
-
 # Private Databases
 class PrivateDatabaseType(StrEnum):
     LOCAL = "LOCAL_DB"
diff --git a/server/src/dp_queries/dp_libraries/open_dp.py b/server/src/dp_queries/dp_libraries/open_dp.py
index 7b10edcd..a25523d4 100644
--- a/server/src/dp_queries/dp_libraries/open_dp.py
+++ b/server/src/dp_queries/dp_libraries/open_dp.py
@@ -1,5 +1,5 @@
 import opendp as dp
-from constants import DPLibraries, OpenDPInputType, OpenDPMeasurement
+from constants import DPLibraries, OpenDPMeasurement
 from dp_queries.dp_querier import DPQuerier
 from opendp.mod import enable_features
 from opendp_logger import make_load_json
@@ -76,17 +76,9 @@ def cost(self, query_json: OpenDPInp) -> tuple[float, float]:
     def query(self, query_json: OpenDPInp) -> str:
         opendp_pipe = reconstruct_measurement_pipeline(query_json.opendp_json)
 
-        match query_json.input_data_type:
-            case OpenDPInputType.DF:
-                input_data = self.private_dataset.get_pandas_df().to_csv(
-                    header=False, index=False
-                )
-            case OpenDPInputType.PATH:
-                input_data = self.private_dataset.get_local_path()
-            case _:
-                raise InvalidQueryException(
-                    f"Invalid input data type {query_json.input_data_type}"
-                )
+        input_data = self.private_dataset.get_pandas_df().to_csv(
+            header=False, index=False
+        )
 
         try:
             release_data = opendp_pipe(input_data)
diff --git a/server/src/dp_queries/dp_libraries/smartnoise_sql.py b/server/src/dp_queries/dp_libraries/smartnoise_sql.py
index f258e4b7..f6e56a60 100644
--- a/server/src/dp_queries/dp_libraries/smartnoise_sql.py
+++ b/server/src/dp_queries/dp_libraries/smartnoise_sql.py
@@ -32,7 +32,7 @@ def cost(self, query_json: SNSQLInpCost) -> List[float]:
         except Exception as e:
             raise ExternalLibraryException(
                 DPLibraries.SMARTNOISE_SQL,
-                "Error obtaining cost:" + str(e),
+                "Error obtaining cost: " + str(e),
             )
 
         return result
@@ -62,14 +62,15 @@ def query(self, query_json: SNSQLInp, nb_iter: int = 0) -> dict:
 
         if not query_json.postprocess:
             result = list(result)
-
-        cols = result.pop(0)
+            cols = [f"res_{i}" for i in range(len(result))]
+        else:
+            cols = result.pop(0)
         if result == []:
             raise ExternalLibraryException(
                 DPLibraries.SMARTNOISE_SQL,
                 f"SQL Reader generated empty results,"
                 f"Epsilon: {epsilon} and Delta: {delta} are too small"
-                "to generate output.",
+                " to generate output.",
             )
 
         df_res = pd.DataFrame(result, columns=cols)
diff --git a/server/src/utils/example_inputs.py b/server/src/utils/example_inputs.py
index 697749e9..89838ab0 100644
--- a/server/src/utils/example_inputs.py
+++ b/server/src/utils/example_inputs.py
@@ -1,40 +1,41 @@
 # Dummy queries
-DUMMY_EPSILON = 1e32 * 1.0
-DUMMY_DELTA = 1.0
+DUMMY_EPSILON = 100.0
+DUMMY_DELTA = 0.99
 
 # Dummy dataset generation
 DUMMY_NB_ROWS = 100
 DUMMY_SEED = 42
 
 # DUMMY dataset name
-IRIS_DATASET = "IRIS"
+PENGUIN_DATASET = "PENGUIN"
+SMARTNOISE_QUERY_EPSILON = 0.1
+SMARTNOISE_QUERY_DELTA = 0.00001
 
-
-example_get_db_data = {
-    "dataset_name": IRIS_DATASET,
+example_get_admin_db_data = {
+    "dataset_name": PENGUIN_DATASET,
 }
 
 example_get_dummy_dataset = {
-    "dataset_name": IRIS_DATASET,
+    "dataset_name": PENGUIN_DATASET,
     "dummy_nb_rows": DUMMY_NB_ROWS,
     "dummy_seed": DUMMY_SEED,
 }
 
 example_smartnoise_sql = {
     "query_str": "SELECT COUNT(*) AS NB_ROW FROM Schema.Table",
-    "dataset_name": IRIS_DATASET,
-    "epsilon": 0.1,
-    "delta": 0.00001,
-    "mechanisms": {"count": "discrete_gaussian"},
+    "dataset_name": PENGUIN_DATASET,
+    "epsilon": SMARTNOISE_QUERY_EPSILON,
+    "delta": SMARTNOISE_QUERY_DELTA,
+    "mechanisms": {"count": "gaussian"},
     "postprocess": True,
 }
 
 example_dummy_smartnoise_sql = {
     "query_str": "SELECT COUNT(*) AS NB_ROW FROM Schema.Table",
-    "dataset_name": IRIS_DATASET,
+    "dataset_name": PENGUIN_DATASET,
     "epsilon": DUMMY_EPSILON,
     "delta": DUMMY_DELTA,
-    "mechanisms": {"count": "discrete_gaussian"},
+    "mechanisms": {"count": "gaussian"},
     "postprocess": False,
     "dummy_nb_rows": DUMMY_NB_ROWS,
     "dummy_seed": DUMMY_SEED,
@@ -42,89 +43,23 @@
 
 example_smartnoise_sql_cost = {
     "query_str": "SELECT COUNT(*) AS NB_ROW FROM Schema.Table",
-    "dataset_name": IRIS_DATASET,
-    "epsilon": 0.1,
-    "delta": 0.00001,
-    "mechanisms": {"count": "discrete_gaussian"},
+    "dataset_name": PENGUIN_DATASET,
+    "epsilon": SMARTNOISE_QUERY_EPSILON,
+    "delta": SMARTNOISE_QUERY_DELTA,
+    "mechanisms": {"count": "gaussian"},
 }
 
+meas_pipeline = '{"version": "0.8.0", "ast": {"_type": "partial_chain", "lhs": {"_type": "partial_chain", "lhs": {"_type": "partial_chain", "lhs": {"_type": "partial_chain", "lhs": {"_type": "partial_chain", "lhs": {"_type": "constructor", "func": "make_chain_tt", "module": "combinators", "args": [{"_type": "constructor", "func": "make_select_column", "module": "transformations", "kwargs": {"key": "bill_length_mm", "TOA": "String"}}, {"_type": "constructor", "func": "make_split_dataframe", "module": "transformations", "kwargs": {"separator": ",", "col_names": {"_type": "list", "_items": ["species", "island", "bill_length_mm", "bill_depth_mm", "flipper_length_mm", "body_mass_g", "sex"]}}}]}, "rhs": {"_type": "constructor", "func": "then_cast_default", "module": "transformations", "kwargs": {"TOA": "f64"}}}, "rhs": {"_type": "constructor", "func": "then_clamp", "module": "transformations", "kwargs": {"bounds": [30.0, 65.0]}}}, "rhs": {"_type": "constructor", "func": "then_resize", "module": "transformations", "kwargs": {"size": 346, "constant": 43.61}}}, "rhs": {"_type": "constructor", "func": "then_variance", "module": "transformations"}}, "rhs": {"_type": "constructor", "func": "then_laplace", "module": "measurements", "kwargs": {"scale": 5.0}}}}'  # noqa: E501
+
 example_opendp = {
-    "dataset_name": IRIS_DATASET,
-    "opendp_json": {
-        "version": "0.8.0",
-        "ast": {
-            "func": "make_chain_tt",
-            "module": "comb",
-            "type": "Transformation",
-            "args": [
-                {
-                    "func": "make_select_column",
-                    "module": "trans",
-                    "type": "Transformation",
-                    "args": [],
-                    "kwargs": {
-                        "key": "income",
-                        "TOA": "py_type:str",
-                    },
-                },
-                {
-                    "func": "make_split_dataframe",
-                    "module": "trans",
-                    "type": "Transformation",
-                    "args": [],
-                    "kwargs": {
-                        "separator": ",",
-                        "col_names": [
-                            "hello",
-                            "world",
-                        ],
-                    },
-                },
-            ],
-            "kwargs": {},
-        },
-    },
-    "input_data_type": "df",
+    "dataset_name": PENGUIN_DATASET,
+    "opendp_json": meas_pipeline,
     "fixed_delta": 1e-6,
 }
 
 example_dummy_opendp = {
-    "dataset_name": IRIS_DATASET,
-    "opendp_json": {
-        "version": "0.8.0",
-        "ast": {
-            "func": "make_chain_tt",
-            "module": "comb",
-            "type": "Transformation",
-            "args": [
-                {
-                    "func": "make_select_column",
-                    "module": "trans",
-                    "type": "Transformation",
-                    "args": [],
-                    "kwargs": {
-                        "key": "income",
-                        "TOA": "py_type:str",
-                    },
-                },
-                {
-                    "func": "make_split_dataframe",
-                    "module": "trans",
-                    "type": "Transformation",
-                    "args": [],
-                    "kwargs": {
-                        "separator": ",",
-                        "col_names": [
-                            "hello",
-                            "world",
-                        ],
-                    },
-                },
-            ],
-            "kwargs": {},
-        },
-    },
-    "input_data_type": "df",
+    "dataset_name": PENGUIN_DATASET,
+    "opendp_json": meas_pipeline,
     "fixed_delta": 1e-6,
     "dummy_nb_rows": DUMMY_NB_ROWS,
     "dummy_seed": DUMMY_SEED,
diff --git a/server/src/utils/input_models.py b/server/src/utils/input_models.py
index ee95a44d..04c30df5 100644
--- a/server/src/utils/input_models.py
+++ b/server/src/utils/input_models.py
@@ -76,14 +76,12 @@ class SNSQLInpCost(BasicModel):
 class OpenDPInp(BasicModel):
     dataset_name: str
     opendp_json: str
-    input_data_type: str
     fixed_delta: Optional[float] = None
 
 
 class DummyOpenDPInp(BasicModel):
     dataset_name: str
     opendp_json: str
-    input_data_type: str
     dummy_nb_rows: int
     dummy_seed: int
     fixed_delta: Optional[float] = None


Test patch:
diff --git a/server/src/tests/__init__.py b/server/src/tests/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/server/src/tests/test_api.py b/server/src/tests/test_api.py
new file mode 100644
index 00000000..8c0f4ee8
--- /dev/null
+++ b/server/src/tests/test_api.py
@@ -0,0 +1,490 @@
+from fastapi import status
+from fastapi.testclient import TestClient
+import json
+from io import StringIO
+import pandas as pd
+import unittest
+
+from app import app
+
+from constants import DPLibraries, EPSILON_LIMIT
+from utils.example_inputs import (
+    DUMMY_NB_ROWS,
+    example_get_admin_db_data,
+    example_get_dummy_dataset,
+    example_smartnoise_sql,
+    example_dummy_smartnoise_sql,
+    example_smartnoise_sql_cost,
+    example_opendp,
+    example_dummy_opendp,
+    PENGUIN_DATASET,
+    SMARTNOISE_QUERY_DELTA,
+    SMARTNOISE_QUERY_EPSILON,
+)
+from utils.loggr import LOG
+
+INITAL_EPSILON = 10
+INITIAL_DELTA = 0.005
+
+
+class TestRootAPIEndpoint(unittest.TestCase):
+    def setUp(self) -> None:
+        print("TestRootAPIEndpoint")
+        self.user_name = "Dr. Antartica"
+        self.dataset = PENGUIN_DATASET
+        self.headers = {
+            "Content-type": "application/json",
+            "Accept": "*/*",
+        }
+        self.headers["user-name"] = self.user_name
+
+    def test_state(self) -> None:
+        with TestClient(app, headers=self.headers) as client:
+            response = client.get("/state", headers=self.headers)
+            assert response.status_code == status.HTTP_200_OK
+
+            response_dict = json.loads(response.content.decode("utf8"))
+            assert response_dict["requested_by"] == self.user_name
+            assert response_dict["state"]["LIVE"]
+
+    def test_get_dataset_metadata(self) -> None:
+        with TestClient(app) as client:
+            # Expect to work
+            response = client.post(
+                "/get_dataset_metadata",
+                json=example_get_admin_db_data,
+                headers=self.headers,
+            )
+            assert response.status_code == status.HTTP_200_OK
+
+            metadata = json.loads(response.content.decode("utf8"))
+            assert isinstance(metadata, dict), "metadata should be a dict"
+            assert "max_ids" in metadata, "max_ids should be in metadata"
+            assert "row_privacy" in metadata, "max_ids should be in metadata"
+
+            # Expect to fail: dataset does not exist
+            fake_dataset = "I_do_not_exist"
+            response = client.post(
+                "/get_dataset_metadata",
+                json={"dataset_name": fake_dataset},
+                headers=self.headers,
+            )
+            assert response.status_code == status.HTTP_400_BAD_REQUEST
+            assert response.json() == {
+                "InvalidQueryException": f"Dataset {fake_dataset} does not "
+                + "exists. Please, verify the client object initialisation."
+            }
+
+    def test_get_dummy_dataset(self) -> None:
+        with TestClient(app) as client:
+            # Expect to work
+            response = client.post(
+                "/get_dummy_dataset", json=example_get_dummy_dataset
+            )
+            assert response.status_code == status.HTTP_200_OK
+
+            data = response.content.decode("utf8")
+            df = pd.read_csv(StringIO(data))
+            assert isinstance(
+                df, pd.DataFrame
+            ), "Response should be a pd.DataFrame"
+            assert (
+                df.shape[0] == DUMMY_NB_ROWS
+            ), "Dummy pd.DataFrame does not have expected number of rows"
+
+            # Expect to fail: dataset does not exist
+            fake_dataset = "I_do_not_exist"
+            response = client.post(
+                "/get_dummy_dataset",
+                json={
+                    "dataset_name": fake_dataset,
+                    "dummy_nb_rows": DUMMY_NB_ROWS,
+                    "dummy_seed": 0,
+                },
+                headers=self.headers,
+            )
+            assert response.status_code == status.HTTP_400_BAD_REQUEST
+            assert response.json() == {
+                "InvalidQueryException": f"Dataset {fake_dataset} does not "
+                + "exists. Please, verify the client object initialisation."
+            }
+
+            # Expect to fail: missing argument dummy_nb_rows
+            response = client.post(
+                "/get_dummy_dataset",
+                json={
+                    "dataset_name": PENGUIN_DATASET,
+                },
+                headers=self.headers,
+            )
+            LOG.error(response.json())
+            assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
+
+    def test_smartnoise_query(self) -> None:
+        with TestClient(app, headers=self.headers) as client:
+            # Expect to work
+            response = client.post(
+                "/smartnoise_query",
+                json=example_smartnoise_sql,
+                headers=self.headers,
+            )
+            assert response.status_code == status.HTTP_200_OK
+
+            response_dict = json.loads(response.content.decode("utf8"))
+            assert response_dict["requested_by"] == self.user_name
+            assert response_dict["query_response"]["columns"] == ["NB_ROW"]
+            assert response_dict["query_response"]["data"][0][0] > 0
+            assert response_dict["spent_epsilon"] == SMARTNOISE_QUERY_EPSILON
+            assert response_dict["spent_delta"] >= SMARTNOISE_QUERY_DELTA
+
+            # Expect to fail: missing parameters: delta and mechanisms
+            response = client.post(
+                "/smartnoise_query",
+                json={
+                    "query_str": "SELECT COUNT(*) AS NB_ROW FROM Schema.Table",
+                    "dataset_name": PENGUIN_DATASET,
+                    "epsilon": SMARTNOISE_QUERY_EPSILON,
+                    "postprocess": True,
+                },
+                headers=self.headers,
+            )
+            assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
+
+            response_dict = json.loads(response.content.decode("utf8"))[
+                "detail"
+            ]
+            assert response_dict[0]["type"] == "missing"
+            assert response_dict[0]["loc"] == ["body", "delta"]
+            assert response_dict[1]["type"] == "missing"
+            assert response_dict[1]["loc"] == ["body", "mechanisms"]
+
+            # Expect to fail: query does not make sense
+            input_smartnoise = dict(example_smartnoise_sql)
+            input_smartnoise[
+                "query_str"
+            ] = "SELECT AVG(bill) FROM Schema.Table"  # no 'bill' column
+            response = client.post(
+                "/smartnoise_query",
+                json=input_smartnoise,
+                headers=self.headers,
+            )
+            LOG.error(response)
+            LOG.error(response.json())
+            assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
+            assert response.json() == {
+                "ExternalLibraryException": "Error obtaining cost: "
+                + "Column cannot be found bill",
+                "library": "smartnoise_sql",
+            }
+
+            # Expect to fail: dataset without access
+            input_smartnoise = dict(example_smartnoise_sql)
+            input_smartnoise["dataset_name"] = "IRIS"
+            response = client.post(
+                "/smartnoise_query",
+                json=input_smartnoise,
+                headers=self.headers,
+            )
+            assert response.status_code == status.HTTP_403_FORBIDDEN
+            assert response.json() == {
+                "UnauthorizedAccessException": "Internal server error. "
+                + "Please contact the administrator of this service."
+            }  # TODO: more meaningful error message
+
+    def test_dummy_smartnoise_query(self) -> None:
+        with TestClient(app) as client:
+            # Expect to work
+            response = client.post(
+                "/dummy_smartnoise_query", json=example_dummy_smartnoise_sql
+            )
+            assert response.status_code == status.HTTP_200_OK
+
+            response_dict = json.loads(response.content.decode("utf8"))
+            assert response_dict["query_response"]["columns"] == ["res_0"]
+            assert response_dict["query_response"]["data"][0][0] > 0
+            assert response_dict["query_response"]["data"][0][0] < 200
+
+    def test_smartnoise_cost(self) -> None:
+        with TestClient(app) as client:
+            # Expect to work
+            response = client.post(
+                "/estimate_smartnoise_cost", json=example_smartnoise_sql_cost
+            )
+            assert response.status_code == status.HTTP_200_OK
+
+            response_dict = json.loads(response.content.decode("utf8"))
+            LOG.error(response_dict)
+            assert response_dict["epsilon_cost"] == SMARTNOISE_QUERY_EPSILON
+            assert response_dict["delta_cost"] > SMARTNOISE_QUERY_DELTA
+
+    def test_opendp_query(self) -> None:
+        with TestClient(app, headers=self.headers) as client:
+            # Expect to work
+            response = client.post(
+                "/opendp_query",
+                json=example_opendp,
+            )
+            assert response.status_code == status.HTTP_200_OK
+
+            response_dict = json.loads(response.content.decode("utf8"))
+            assert response_dict["requested_by"] == self.user_name
+            assert response_dict["query_response"] > 0
+            assert response_dict["spent_epsilon"] > 0.1
+            assert response_dict["spent_delta"] == 0
+
+            # Expect to fail: transormation instead of measurement
+            trans_pipeline = '{"version": "0.8.0", "ast": {"_type": "partial_chain", "lhs": {"_type": "partial_chain", "lhs": {"_type": "partial_chain", "lhs": {"_type": "partial_chain", "lhs": {"_type": "constructor", "func": "make_chain_tt", "module": "combinators", "args": [{"_type": "constructor", "func": "make_select_column", "module": "transformations", "kwargs": {"key": "bill_length_mm", "TOA": "String"}}, {"_type": "constructor", "func": "make_split_dataframe", "module": "transformations", "kwargs": {"separator": ",", "col_names": {"_type": "list", "_items": ["species", "island", "bill_length_mm", "bill_depth_mm", "flipper_length_mm", "body_mass_g", "sex"]}}}]}, "rhs": {"_type": "constructor", "func": "then_cast_default", "module": "transformations", "kwargs": {"TOA": "f64"}}}, "rhs": {"_type": "constructor", "func": "then_clamp", "module": "transformations", "kwargs": {"bounds": [30.0, 65.0]}}}, "rhs": {"_type": "constructor", "func": "then_resize", "module": "transformations", "kwargs": {"size": 346, "constant": 43.61}}}, "rhs": {"_type": "constructor", "func": "then_variance", "module": "transformations"}}}'  # noqa: E501
+            response = client.post(
+                "/opendp_query",
+                json={
+                    "dataset_name": PENGUIN_DATASET,
+                    "opendp_json": trans_pipeline,
+                },
+            )
+            assert response.status_code == status.HTTP_400_BAD_REQUEST
+            assert response.json() == {
+                "InvalidQueryException": "The pipeline provided is not a "
+                + "measurement. It cannot be processed in this server."
+            }
+
+    def test_dummy_opendp_query(self) -> None:
+        with TestClient(app) as client:
+            # Expect to work
+            response = client.post(
+                "/dummy_opendp_query", json=example_dummy_opendp
+            )
+            assert response.status_code == status.HTTP_200_OK
+            response_dict = json.loads(response.content.decode("utf8"))
+            assert response_dict["query_response"] > 0
+
+    def test_opendp_cost(self) -> None:
+        with TestClient(app) as client:
+            # Expect to work
+            response = client.post(
+                "/estimate_opendp_cost", json=example_opendp
+            )
+            assert response.status_code == status.HTTP_200_OK
+
+            response_dict = json.loads(response.content.decode("utf8"))
+            assert response_dict["epsilon_cost"] > 0.1
+            assert response_dict["delta_cost"] == 0
+
+    def test_get_initial_budget(self) -> None:
+        with TestClient(app, headers=self.headers) as client:
+            # Expect to work
+            response = client.post(
+                "/get_initial_budget", json=example_get_admin_db_data
+            )
+            assert response.status_code == status.HTTP_200_OK
+
+            response_dict = json.loads(response.content.decode("utf8"))
+            assert response_dict["initial_epsilon"] == INITAL_EPSILON
+            assert response_dict["initial_delta"] == INITIAL_DELTA
+
+            # Query to spend budget
+            _ = client.post(
+                "/smartnoise_query",
+                json=example_smartnoise_sql,
+                headers=self.headers,
+            )
+
+            # Response should stay the same
+            response_2 = client.post(
+                "/get_initial_budget", json=example_get_admin_db_data
+            )
+            assert response_2.status_code == status.HTTP_200_OK
+            response_dict_2 = json.loads(response_2.content.decode("utf8"))
+            assert response_dict_2 == response_dict
+
+    def test_get_total_spent_budget(self) -> None:
+        with TestClient(app, headers=self.headers) as client:
+            # Expect to work
+            response = client.post(
+                "/get_total_spent_budget", json=example_get_admin_db_data
+            )
+            assert response.status_code == status.HTTP_200_OK
+
+            response_dict = json.loads(response.content.decode("utf8"))
+            assert response_dict["total_spent_epsilon"] == 0
+            assert response_dict["total_spent_delta"] == 0
+
+            # Query to spend budget
+            _ = client.post(
+                "/smartnoise_query",
+                json=example_smartnoise_sql,
+                headers=self.headers,
+            )
+
+            # Response should have updated spent budget
+            response_2 = client.post(
+                "/get_total_spent_budget", json=example_get_admin_db_data
+            )
+            assert response_2.status_code == status.HTTP_200_OK
+
+            response_dict_2 = json.loads(response_2.content.decode("utf8"))
+            assert response_dict_2 != response_dict
+            assert (
+                response_dict_2["total_spent_epsilon"]
+                == SMARTNOISE_QUERY_EPSILON
+            )
+            assert (
+                response_dict_2["total_spent_delta"] >= SMARTNOISE_QUERY_DELTA
+            )
+
+    def test_get_remaining_budget(self) -> None:
+        with TestClient(app, headers=self.headers) as client:
+            # Expect to work
+            response = client.post(
+                "/get_remaining_budget", json=example_get_admin_db_data
+            )
+            assert response.status_code == status.HTTP_200_OK
+
+            response_dict = json.loads(response.content.decode("utf8"))
+            assert response_dict["remaining_epsilon"] == INITAL_EPSILON
+            assert response_dict["remaining_delta"] == INITIAL_DELTA
+
+            # Query to spend budget
+            _ = client.post(
+                "/smartnoise_query",
+                json=example_smartnoise_sql,
+                headers=self.headers,
+            )
+
+            # Response should have removed spent budget
+            response_2 = client.post(
+                "/get_remaining_budget", json=example_get_admin_db_data
+            )
+            assert response_2.status_code == status.HTTP_200_OK
+
+            response_dict_2 = json.loads(response_2.content.decode("utf8"))
+            assert response_dict_2 != response_dict
+            assert (
+                response_dict_2["remaining_epsilon"]
+                == INITAL_EPSILON - SMARTNOISE_QUERY_EPSILON
+            )
+            assert (
+                response_dict_2["remaining_delta"]
+                <= INITIAL_DELTA - SMARTNOISE_QUERY_DELTA
+            )
+
+    def test_get_previous_queries(self) -> None:
+        with TestClient(app, headers=self.headers) as client:
+            # Expect to work
+            response = client.post(
+                "/get_previous_queries", json=example_get_admin_db_data
+            )
+            assert response.status_code == status.HTTP_200_OK
+
+            response_dict = json.loads(response.content.decode("utf8"))
+            assert response_dict["previous_queries"] == []
+
+            # Query to archive 1 (smartnoise)
+            query_res = client.post(
+                "/smartnoise_query",
+                json=example_smartnoise_sql,
+                headers=self.headers,
+            )
+            query_res = json.loads(query_res.content.decode("utf8"))
+
+            # Response should have one element in list
+            response_2 = client.post(
+                "/get_previous_queries", json=example_get_admin_db_data
+            )
+            assert response_2.status_code == status.HTTP_200_OK
+
+            response_dict_2 = json.loads(response_2.content.decode("utf8"))
+            assert len(response_dict_2["previous_queries"]) == 1
+            assert (
+                response_dict_2["previous_queries"][0]["dp_librairy"]
+                == DPLibraries.SMARTNOISE_SQL
+            )
+            assert (
+                response_dict_2["previous_queries"][0]["client_input"]
+                == example_smartnoise_sql
+            )
+            assert (
+                response_dict_2["previous_queries"][0]["response"] == query_res
+            )
+
+            # Query to archive 2 (opendp)
+            query_res = client.post(
+                "/opendp_query",
+                json=example_opendp,
+            )
+            query_res = json.loads(query_res.content.decode("utf8"))
+
+            # Response should have two elements in list
+            response_3 = client.post(
+                "/get_previous_queries", json=example_get_admin_db_data
+            )
+            assert response_3.status_code == status.HTTP_200_OK
+
+            response_dict_3 = json.loads(response_3.content.decode("utf8"))
+            assert len(response_dict_3["previous_queries"]) == 2
+            assert (
+                response_dict_3["previous_queries"][0]
+                == response_dict_2["previous_queries"][0]
+            )
+            assert (
+                response_dict_3["previous_queries"][1]["dp_librairy"]
+                == DPLibraries.OPENDP
+            )
+            assert (
+                response_dict_3["previous_queries"][1]["client_input"]
+                == example_opendp
+            )
+            assert (
+                response_dict_3["previous_queries"][1]["response"] == query_res
+            )
+
+    def test_budget_limit_logic(self) -> None:
+        with TestClient(app, headers=self.headers) as client:
+            # Should fail: too much budget on one go
+            smartnoise_body = dict(example_smartnoise_sql)
+            smartnoise_body["epsilon"] = EPSILON_LIMIT * 2
+
+            response = client.post(
+                "/smartnoise_query",
+                json=smartnoise_body,
+                headers=self.headers,
+            )
+
+            assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
+            assert response.json() == {
+                "detail": [
+                    {
+                        "type": "less_than_equal",
+                        "loc": ["body", "epsilon"],
+                        "msg": "Input should be less than or equal to 5",
+                        "input": EPSILON_LIMIT * 2,
+                        "ctx": {"le": EPSILON_LIMIT},
+                    }
+                ]
+            }
+
+            # Should fail: too much budget after three queries
+            smartnoise_body["epsilon"] = 4.0
+            response = client.post(
+                "/smartnoise_query",
+                json=smartnoise_body,
+                headers=self.headers,
+            )  # spent 4.0 (total_spent = 4.0 <= INTIAL_BUDGET = 10.0)
+            assert response.status_code == status.HTTP_200_OK
+
+            response = client.post(
+                "/smartnoise_query",
+                json=smartnoise_body,
+                headers=self.headers,
+            )  # spent 2*4.0 (total_spent = 8.0 <= INTIAL_BUDGET = 10.0)
+            assert response.status_code == status.HTTP_200_OK
+
+            response = client.post(
+                "/smartnoise_query",
+                json=smartnoise_body,
+                headers=self.headers,
+            )  # spent 3*4.0 (total_spent = 12.0 > INTIAL_BUDGET = 10.0)
+            assert response.status_code == status.HTTP_403_FORBIDDEN
+            assert response.json() == {
+                "UnauthorizedAccessException": "Internal server error. "
+                + "Please contact the administrator of this service."
+            }