From 7570b5a5450b71f30291eef9406570c6f7c59246 Mon Sep 17 00:00:00 2001 From: "tom.mansion" Date: Wed, 5 Feb 2025 16:14:11 +0100 Subject: [PATCH 1/2] DP DebiAI-gui parameters --- .../dataInsertion/dataProviders/quickStart.md | 73 ++++++++++++------- .../gettingStarted/installation/README.md | 9 ++- 2 files changed, 53 insertions(+), 29 deletions(-) diff --git a/documentation/dataInsertion/dataProviders/quickStart.md b/documentation/dataInsertion/dataProviders/quickStart.md index 66484b8..78816e0 100644 --- a/documentation/dataInsertion/dataProviders/quickStart.md +++ b/documentation/dataInsertion/dataProviders/quickStart.md @@ -9,29 +9,29 @@ There are multiple ways to create a DebiAI Data Provider: title: 'Python module', description: 'Create a Data Provider from a single Python file', imageLink: '/install/python.svg', - elementIdDestination: '_1-debiai-data-provider-python-module-recommended', + elementIdDestination: 'debiai-data-provider-python-module-recommended', tag: 'Recommended' }, { title: 'Service templates', description: 'Generate a Data Provider using a pre-built template', imageLink: '/install/template.svg', - elementIdDestination: '_2-data-provider-templates' + elementIdDestination: 'data-provider-templates' }, { title: 'Custom implementation', description: 'Build a Data Provider from scratch', imageLink: '/install/build.svg', - elementIdDestination: '_3-custom-data-provider-implementation' + elementIdDestination: 'custom-data-provider-implementation' } ]" /> -### 1. DebiAI Data Provider Python Module (Recommended) +### DebiAI Data Provider Python Module (Recommended) The simplest way to create a Data Provider is by using the [DebiAI Data Provider Python module](https://github.com/debiai/easy-data-provider). This module allows you to define access methods and event handlers within a single Python class. -### 2. Data Provider Templates +### Data Provider Templates To streamline Data Provider creation, we offer **quick-start templates**. Currently, templates are available for: @@ -39,7 +39,7 @@ To streamline Data Provider creation, we offer **quick-start templates**. Curren Want support for another language? [Let us know](https://github.com/debiai/data-provider-nodejs-template/issues/new). -### 3. Custom Data Provider Implementation +### Custom Data Provider Implementation You can build your own Data Provider as long as it follows the [DebiAI Data Provider API](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/debiai/data-provider-nodejs-template/main/data-provider-API.yaml). @@ -48,39 +48,46 @@ You can build your own Data Provider as long as it follows the [DebiAI Data Prov After creating your Data Provider, you must configure DebiAI to access it: -::: warning -**DebiAI must be able to access your Data Provider.** +--- -- If running locally, use `localhost` as the URL. -- If hosted externally, use the **public IP address**. -- When using **Docker**, you may need to use the public IP or `--network host` to access a provider deployed on `localhost`. - More details: [Docker documentation](https://docs.docker.com/network/host/). - ::: +### With DebiAI-gui ---- +If you are using the [DebiAI-gui Python package](../../introduction/gettingStarted/installation/README.md#debiai-gui-python-package) to run DebiAI, you can add Data-providers directly as parameters: + +```bash +debiai-gui start -dp http://localhost:4000 http://localhost:8000 +``` -### 1. Connecting via the Dashboard +DebiAI will automatically connect to the specified Data Providers. + +### Connecting via the Dashboard You can add a Data Provider through the **DebiAI dashboard**: @@ -97,9 +104,7 @@ You can add a Data Provider through the **DebiAI dashboard**: **Dashboard-added providers are not persistent.** Restarting DebiAI will remove them. Use **environment variables** or a **configuration file** for persistence. ::: ---- - -### 2. Connecting via Environment Variables +### Connecting via Environment Variables For deployments, you can define environment variables to specify provider URLs. @@ -133,9 +138,9 @@ services: - DEBIAI_WEB_DATA_PROVIDER_MyDataProvider2=http://localhost:3010/ ``` -For a full list fo environment variables, check the [docker-compose-build.yml](https://github.com/debiai/debiai/blob/main/docker-compose-build.yml) file. +For a full list fo environment variables, check the [config.env](https://github.com/debiai/DebiAI/blob/main/debiaiServer/config/config.env) file. -### 3. Connecting via Configuration File +### Connecting via Configuration File You can also configure providers in config.ini: Example `(debiai/debiaiServer/config/config.ini)`: @@ -148,8 +153,20 @@ MyDataProvider2 = http://localhost:3010/ After editing, restart DebiAI (or rebuild the Docker image if using containers). -::: tip Priority Order: -Environment variables override the configuration file settings. -::: +::: tip Configuration priority order: + +1. DebiAI-gui python module parameters +2. Environment variables +3. Configuration file settings. + ::: If the provider is accessible and follows the API, DebiAI will list the projects in the dashboard. + +::: warning +**DebiAI must be able to access your Data Provider.** + +- If running locally, use `localhost` as the URL. +- If hosted externally, use the **public IP address**. +- When using **Docker**, you may need to use the public IP or `--network host` to access a provider deployed on `localhost`. + More details: [Docker documentation](https://docs.docker.com/network/host/). + ::: diff --git a/documentation/introduction/gettingStarted/installation/README.md b/documentation/introduction/gettingStarted/installation/README.md index 0d12d0e..afaa872 100644 --- a/documentation/introduction/gettingStarted/installation/README.md +++ b/documentation/introduction/gettingStarted/installation/README.md @@ -71,13 +71,20 @@ DebiAI needs a place to store the data, on startup it will ask you to provide a Debiai will then be available on [http://localhost:3000/](http://localhost:3000/) -**Parameters** +### Parameters ```bash +# Specify the the configuration folder path: +debiai-gui start --data-folder debiai-data + # Start DebiAI on a different port: debiai-gui start --port 4000 +# Prevent the web browser from opening automatically: +debiai-gui start --no-browser + # Display help: debiai-gui --help +debiai-gui start --help ``` ## Official Docker image From 9e4e27a0379266ae769824dbd92417e6e6309301 Mon Sep 17 00:00:00 2001 From: "tom.mansion" Date: Wed, 5 Feb 2025 16:14:26 +0100 Subject: [PATCH 2/2] Algo-providers documentation update --- documentation/.vuepress/config.js | 39 ++++-- .../.vuepress/public/install/addBlock.svg | 4 + .../.vuepress/public/install/gears.svg | 50 +++++++ .../.vuepress/public/install/heartFile.svg | 4 + .../.vuepress/public/install/terminal.svg | 5 + documentation/customAlgorithms/README.md | 31 +++++ .../customAlgorithms/algoProviders/README.md | 87 ++++++++++++ .../algoProviders/addingAlgoProviders.md | 126 ++++++++++++++++++ .../algoProviders/algoProviderTemplates.md | 11 ++ .../algoProviders/customImplementation.md | 18 +++ .../algoProviders/easyAlgoProvider.md | 62 +++++++++ .../algoProviders/easyAlgoProviderResults.png | Bin 0 -> 59504 bytes .../algoProviders/implementInBackend.md | 4 +- .../algo_providers_menu_1.png | Bin .../algo_providers_menu_2.png | Bin .../algo_providers_menu_3.png | Bin .../algo_providers_menu_4.png | Bin .../algo_providers_menu_5.png | Bin .../algo_providers_menu_6.png | Bin .../customAlgorithms/howToUseAlgorithms.md | 35 +++++ .../customAlgorithms/integratedAlgorithms.md | 12 ++ .../menu.png | Bin documentation/dashboard/README.md | 2 +- .../dashboard/algoProviders/README.md | 96 ------------- .../dashboard/algoProviders/algoProviders.md | 45 ------- .../algoProviders/integratedAlgorithms.md | 13 -- 26 files changed, 477 insertions(+), 167 deletions(-) create mode 100644 documentation/.vuepress/public/install/addBlock.svg create mode 100644 documentation/.vuepress/public/install/gears.svg create mode 100644 documentation/.vuepress/public/install/heartFile.svg create mode 100644 documentation/.vuepress/public/install/terminal.svg create mode 100644 documentation/customAlgorithms/README.md create mode 100644 documentation/customAlgorithms/algoProviders/README.md create mode 100644 documentation/customAlgorithms/algoProviders/addingAlgoProviders.md create mode 100644 documentation/customAlgorithms/algoProviders/algoProviderTemplates.md create mode 100644 documentation/customAlgorithms/algoProviders/customImplementation.md create mode 100644 documentation/customAlgorithms/algoProviders/easyAlgoProvider.md create mode 100644 documentation/customAlgorithms/algoProviders/easyAlgoProviderResults.png rename documentation/{dashboard => customAlgorithms}/algoProviders/implementInBackend.md (89%) rename documentation/{dashboard/algoProviders => customAlgorithms}/algo_providers_menu_1.png (100%) rename documentation/{dashboard/algoProviders => customAlgorithms}/algo_providers_menu_2.png (100%) rename documentation/{dashboard/algoProviders => customAlgorithms}/algo_providers_menu_3.png (100%) rename documentation/{dashboard/algoProviders => customAlgorithms}/algo_providers_menu_4.png (100%) rename documentation/{dashboard/algoProviders => customAlgorithms}/algo_providers_menu_5.png (100%) rename documentation/{dashboard/algoProviders => customAlgorithms}/algo_providers_menu_6.png (100%) create mode 100644 documentation/customAlgorithms/howToUseAlgorithms.md create mode 100644 documentation/customAlgorithms/integratedAlgorithms.md rename documentation/{dashboard/algoProviders => customAlgorithms}/menu.png (100%) delete mode 100644 documentation/dashboard/algoProviders/README.md delete mode 100644 documentation/dashboard/algoProviders/algoProviders.md delete mode 100644 documentation/dashboard/algoProviders/integratedAlgorithms.md diff --git a/documentation/.vuepress/config.js b/documentation/.vuepress/config.js index 2e2d5b9..c060b28 100755 --- a/documentation/.vuepress/config.js +++ b/documentation/.vuepress/config.js @@ -94,6 +94,35 @@ module.exports = { ], }, + // Custom algorithms + { + title: "Custom algorithms", + path: "/customAlgorithms/", + collapsable: false, + initialOpenGroupIndex: -1, + children: [ + { + title: "How to use algorithms", + path: "/customAlgorithms/howToUseAlgorithms.md", + }, + { + title: "Integrated algorithms", + path: "/customAlgorithms/integratedAlgorithms.md", + }, + { + title: "Algo-providers", + path: "/customAlgorithms/algoProviders/", + children: [ + "/customAlgorithms/algoProviders/easyAlgoProvider.md", + "/customAlgorithms/algoProviders/algoProviderTemplates.md", + "/customAlgorithms/algoProviders/customImplementation.md", + "/customAlgorithms/algoProviders/implementInBackend.md", + "/customAlgorithms/algoProviders/addingAlgoProviders.md", + ], + }, + ], + }, + // Dashboard { title: "Dashboard", @@ -130,16 +159,6 @@ module.exports = { path: "/dashboard/layouts/", collapsable: true, }, - { - title: "Custom algorithms", - path: "/dashboard/algoProviders/", - collapsable: true, - children: [ - "/dashboard/algoProviders/algoProviders.md", - "/dashboard/algoProviders/implementInBackend.md", - "/dashboard/algoProviders/integratedAlgorithms.md", - ], - }, { title: "Data export", path: "/dashboard/dataExport/", diff --git a/documentation/.vuepress/public/install/addBlock.svg b/documentation/.vuepress/public/install/addBlock.svg new file mode 100644 index 0000000..4f98688 --- /dev/null +++ b/documentation/.vuepress/public/install/addBlock.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/documentation/.vuepress/public/install/gears.svg b/documentation/.vuepress/public/install/gears.svg new file mode 100644 index 0000000..a96371d --- /dev/null +++ b/documentation/.vuepress/public/install/gears.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/documentation/.vuepress/public/install/heartFile.svg b/documentation/.vuepress/public/install/heartFile.svg new file mode 100644 index 0000000..c7a8449 --- /dev/null +++ b/documentation/.vuepress/public/install/heartFile.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/documentation/.vuepress/public/install/terminal.svg b/documentation/.vuepress/public/install/terminal.svg new file mode 100644 index 0000000..5beeb40 --- /dev/null +++ b/documentation/.vuepress/public/install/terminal.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/documentation/customAlgorithms/README.md b/documentation/customAlgorithms/README.md new file mode 100644 index 0000000..4ea913f --- /dev/null +++ b/documentation/customAlgorithms/README.md @@ -0,0 +1,31 @@ +# Adding custom algorithms to DebiAI + +Projects have their own specific needs and sometimes the algorithms that are available in DebiAI are not enough. That's why DebiAI allows you to add your own algorithms. + +Adding an algorithm to DebiAI allows you to use it with the data directly from the dashboard and analyze the results like any other project data. + +Different kinds of algorithms can be added to DebiAI, ranging from data quality to metrics calculation, from data transformation using machine learning models to anomaly detection. + +**Learn more:** + + \ No newline at end of file diff --git a/documentation/customAlgorithms/algoProviders/README.md b/documentation/customAlgorithms/algoProviders/README.md new file mode 100644 index 0000000..1771981 --- /dev/null +++ b/documentation/customAlgorithms/algoProviders/README.md @@ -0,0 +1,87 @@ +# DebiAI Algo-providers + +An Algo-provider is a service that can respond to the algorithms requests of DebiAI. DebiAI will interact with your Algo-provider in two ways: + +- For getting the list of available algorithms +- For running an algorithm and getting the results + +## Creating an Algo-provider + +We offer different ways to create an Algo-provider: + + + +## Algorithms description + +You will need to describe your algorithm in a Json format and then create the implementation of your algorithm. After that, DebiAI will be able to understand your algorithm and run it. + +Here is, for example, the description of a simple moving average algorithm: + +```json +{ + "id": "moving_average", + "name": "Moving average", + "description": "Calculate the moving average of a data.", + "tags": ["calculations"], + "author": "DebiAI", + "version": "1.0.0", + "inputs": [ + { + "name": "data", + "description": "The data to calculate the moving average on.", + "type": "array", + "arrayType": "number", + "lengthMin": 1, + "lengthMax": 100000 + }, + { + "name": "periods", + "description": "The number of periods to calculate the moving average on.", + "type": "number", + "default": 3, + "min": 1, + "max": 100 + } + ], + "outputs": [ + { + "name": "moving_average", + "description": "The moving average of the data. Same length as the data", + "type": "array", + "arrayType": "number" + } + ] +} +``` + +As you can see, the input and output of the algorithm are described. This description is used by DebiAI to understand how to run the algorithm and how to display it in the dashboard and what kind of data it needs. + +To learn more about the algorithms descriptions, you can read the [Algorithm description documentation](https://github.com/debiai/algo-provider-python-template/blob/main/algo-api/README.md). diff --git a/documentation/customAlgorithms/algoProviders/addingAlgoProviders.md b/documentation/customAlgorithms/algoProviders/addingAlgoProviders.md new file mode 100644 index 0000000..6f42195 --- /dev/null +++ b/documentation/customAlgorithms/algoProviders/addingAlgoProviders.md @@ -0,0 +1,126 @@ +# Adding Algo-providers to DebiAI + +Once you have created and deployed your Algo-provider, you can add it to DebiAI. We offer multiple ways to do so: + + + +## With DebiAI-gui + +If you are using the [DebiAI-gui Python package](../../introduction/gettingStarted/installation/README.md#debiai-gui-python-package) to run DebiAI, you can add Algo-providers directly as parameters: + +```bash +debiai-gui start -ap http://localhost:4000 http://localhost:8000 +``` + +Once you have created and deployed your Algo-provider, you can add it to DebiAI. + +## From the dashboard + +You can add your Algo-provider directly from the dashboard. To do so, go to the Algo-providers page from the menu: + +![menu](../menu.png) + +And click on the "Add a new Algo-provider" button: + +![add](../algo_providers_menu_1.png) + +You will need to provide the URL of your Algo-provider. This URL should be the root URL of your Algo-provider, for example: `https://my-algo-provider.com/`. + +![add](../algo_providers_menu_2.png) + +Once you have added your Algo-provider, you will be able to use the algorithms it provides in the Algorithms tab of the analysis dashboard: + +![add](../algo_providers_menu_3.png) + +## Connecting via Environment Variables + +For deployments, you can define environment variables to specify provider URLs. + +### Example: + +```bash +export DEBIAI_ALGO_PROVIDER_MyAlgoProvider1=http://localhost:3000/ +export DEBIAI_ALGO_PROVIDER_MyAlgoProvider2=http://localhost:3010/ +``` + +With Docker: + +```bash +docker run -p 3000:3000 \ + -e DEBIAI_ALGO_PROVIDER_MyAlgoProvider1=http://localhost:3000/ \ + -e DEBIAI_ALGO_PROVIDER_MyAlgoProvider2=http://localhost:3010/ \ + debiai/app +``` + +With Docker Compose: + +```yaml +version: "3.8" +services: + debiai: + image: "debiai/app" + ports: + - "3000:3000" + environment: + - DEBIAI_ALGO_PROVIDER_MyAlgoProvider1=http://localhost:3000/ + - DEBIAI_ALGO_PROVIDER_MyAlgoProvider2=http://localhost:3010/ +``` + +For a full list fo environment variables, check the [config.env](https://github.com/debiai/DebiAI/blob/main/debiaiServer/config/config.env) file. + +## Connecting via Configuration File + +You can also configure providers in config.ini: +Example `(debiai/debiaiServer/config/config.ini)`: + +```ini +[ALGO_PROVIDERS] +MyAlgoProvider1 = http://localhost:3000/ +MyAlgoProvider2 = http://localhost:3010/ +``` + +After editing, restart DebiAI (or rebuild the Docker image if using containers). + +::: tip Configuration priority order: + +1. DebiAI-gui python module parameters +2. Environment variables +3. Configuration file settings. + ::: + +If the Algo-provider is accessible and follows the API, DebiAI will list the algorithms in the dashboard analysis page. + +::: warning +**DebiAI must be able to access your Algo-provider.** + +- If running locally, use `localhost` as the URL. +- If hosted externally, use the **public IP address**. +- When using **Docker**, you may need to use the public IP or `--network host` to access a provider deployed on `localhost`. + More details: [Docker documentation](https://docs.docker.com/network/host/). + ::: diff --git a/documentation/customAlgorithms/algoProviders/algoProviderTemplates.md b/documentation/customAlgorithms/algoProviders/algoProviderTemplates.md new file mode 100644 index 0000000..6baa053 --- /dev/null +++ b/documentation/customAlgorithms/algoProviders/algoProviderTemplates.md @@ -0,0 +1,11 @@ +# Algo-provider templates + +To help you create custom algo-providers, we have created rest api service templates. You can use it as a starting point for your own Algo-provider. + +- Python: [Algo-provider Python template](https://github.com/debiai/algo-provider-python-template). + +:::tip +Using the [algo-provider Python module](./easyAlgoProvider.md) is the easiest and recommended way to create an Algo-provider for DebiAI if you are using Python. Use the Python template if you want to go further with your Algo-provider. +::: + +After creating your Algo-provider, you can add it to DebiAI by providing the URL of your provider. [Learn more on how to add Algo-providers to DebiAI.](./addingAlgoProviders.md#adding-algo-providers-to-debiai) diff --git a/documentation/customAlgorithms/algoProviders/customImplementation.md b/documentation/customAlgorithms/algoProviders/customImplementation.md new file mode 100644 index 0000000..7ca5d80 --- /dev/null +++ b/documentation/customAlgorithms/algoProviders/customImplementation.md @@ -0,0 +1,18 @@ +# Algo-provider from scratch + +An Algo-provider can be made in **any language**, can use **any kind algorithms** and can be hosted on **any platform** as long at the DebiAI algo-provider's API is respected. + +## The API + +The Algo-providers API as been described with OpenAPI 3.0. + +- [Algo-providers API Swagger documentation](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/debiai/algo-provider-python-template/main/algo-api/OpenAPI/Algo_OpenAPI_V0.yaml) +- [Alg-providers API yaml file](https://github.com/debiai/algo-provider-python-template/blob/main/algo-api/OpenAPI/Algo_OpenAPI_V0.yaml). + +## Getting started + +If you want to create an Algo-provider in another language, you just need to respect the [Algo-providers API](#the-api). + +You need help creating your Algo-provider? [Create an issue](https://github.com/debiai/debiai/issues) and we will help you. + +After creating your Algo-provider, you can add it to DebiAI by providing the URL of your provider. [Learn more on how to add Algo-providers to DebiAI.](./addingAlgoProviders.md#adding-algo-providers-to-debiai) diff --git a/documentation/customAlgorithms/algoProviders/easyAlgoProvider.md b/documentation/customAlgorithms/algoProviders/easyAlgoProvider.md new file mode 100644 index 0000000..94db28e --- /dev/null +++ b/documentation/customAlgorithms/algoProviders/easyAlgoProvider.md @@ -0,0 +1,62 @@ +# Algo-provider python module + +The [Algo-provider Python module](https://github.com/debiai/easy-algo-provider) starts a Fast API server that provides a REST API to interact with DebiAI. This is the easiest way to create an Algo-provider for DebiAI. + +## Getting started + +Install the module with pip: + +```bash +pip install algo-provider +``` + +Then, create a Python file with the following content: + +```python +# First define your algorithm following a strict docstring format +def my_algo1(input1: int, input2: int) -> int: + """ + This is a simple algorithm that adds two numbers together. + + Parameters: + input1 (int): The first number to add. + input2 (int): The second number to add. + + Returns: + int: The sum of the two numbers. + """ + return input1 + input2 + +# Then create an AlgoProvider object and add your algorithm to it +from algo_provider import AlgoProvider +provider = AlgoProvider() +provider.add_algo(my_algo1) + +# Finally, start the server +provider.start_server() +``` + +Run the Python file and your algorithm is now available through the Algo-provider API! + +![Expected output](./easyAlgoProviderResults.png) + +The content of the docstring will be used to generate Algo descriptions in the DebiAI interface, and the function will be called with the parameters provided by the user. The return value will be sent back to the user and displayed in the DebiAI interface. + +## Parameters + +You can specify the following parameters when adding an algorithm: + +```python +provider.add_algo( + my_algo_3, + author="DebiAI", + version="1.0.0", + creation_date="2024-01-01", + update_date="2024-01-01", + tags=["Math", "Addition"], +) +``` + +[Algo-provider Python module GitHub page](https://github.com/debiai/easy-algo-provider) + +After creating your Algo-provider, you can add it to DebiAI by providing the URL of your provider. [Learn more on how to add Algo-providers to DebiAI.](./addingAlgoProviders.md#adding-algo-providers-to-debiai) diff --git a/documentation/customAlgorithms/algoProviders/easyAlgoProviderResults.png b/documentation/customAlgorithms/algoProviders/easyAlgoProviderResults.png new file mode 100644 index 0000000000000000000000000000000000000000..6790cd74b15e77d1bf92c57dcc89174fb402fc05 GIT binary patch literal 59504 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

ag=Tgr77J;w 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 KWhy^>3j8mwfXi(F literal 0 HcmV?d00001 diff --git a/documentation/dashboard/algoProviders/implementInBackend.md b/documentation/customAlgorithms/algoProviders/implementInBackend.md similarity index 89% rename from documentation/dashboard/algoProviders/implementInBackend.md rename to documentation/customAlgorithms/algoProviders/implementInBackend.md index 89d0b4c..a5c6c60 100644 --- a/documentation/dashboard/algoProviders/implementInBackend.md +++ b/documentation/customAlgorithms/algoProviders/implementInBackend.md @@ -1,6 +1,6 @@ -# Algorithm in the backend +# Modify DebiAI to add your own algorithms -You can insert Python code directly in the DebiAI backend. This is useful if you want to use an algorithm that you have created in Python, but you don't want to host it yourself. +You can insert Python code directly in the DebiAI backend. This is useful if you want to use an algorithm that you have created in Python, but you don't want to host it yourself, or if you want to contribute to the list of integrated algorithms of DebiAI. DebiAI will run your Python code when you will run the algorithm from the dashboard. Your python code must respect the a format that is described [here](https://github.com/debiai/algo-provider-python-template/blob/main/algo-api/README.md#response) diff --git a/documentation/dashboard/algoProviders/algo_providers_menu_1.png b/documentation/customAlgorithms/algo_providers_menu_1.png similarity index 100% rename from documentation/dashboard/algoProviders/algo_providers_menu_1.png rename to documentation/customAlgorithms/algo_providers_menu_1.png diff --git a/documentation/dashboard/algoProviders/algo_providers_menu_2.png b/documentation/customAlgorithms/algo_providers_menu_2.png similarity index 100% rename from documentation/dashboard/algoProviders/algo_providers_menu_2.png rename to documentation/customAlgorithms/algo_providers_menu_2.png diff --git a/documentation/dashboard/algoProviders/algo_providers_menu_3.png b/documentation/customAlgorithms/algo_providers_menu_3.png similarity index 100% rename from documentation/dashboard/algoProviders/algo_providers_menu_3.png rename to documentation/customAlgorithms/algo_providers_menu_3.png diff --git a/documentation/dashboard/algoProviders/algo_providers_menu_4.png b/documentation/customAlgorithms/algo_providers_menu_4.png similarity index 100% rename from documentation/dashboard/algoProviders/algo_providers_menu_4.png rename to documentation/customAlgorithms/algo_providers_menu_4.png diff --git a/documentation/dashboard/algoProviders/algo_providers_menu_5.png b/documentation/customAlgorithms/algo_providers_menu_5.png similarity index 100% rename from documentation/dashboard/algoProviders/algo_providers_menu_5.png rename to documentation/customAlgorithms/algo_providers_menu_5.png diff --git a/documentation/dashboard/algoProviders/algo_providers_menu_6.png b/documentation/customAlgorithms/algo_providers_menu_6.png similarity index 100% rename from documentation/dashboard/algoProviders/algo_providers_menu_6.png rename to documentation/customAlgorithms/algo_providers_menu_6.png diff --git a/documentation/customAlgorithms/howToUseAlgorithms.md b/documentation/customAlgorithms/howToUseAlgorithms.md new file mode 100644 index 0000000..b9957ad --- /dev/null +++ b/documentation/customAlgorithms/howToUseAlgorithms.md @@ -0,0 +1,35 @@ +# How to use an algorithm from the dashboard + +DebiAI allows you to use algorithms (integrated or custom) directly from the dashboard. This is useful if you want to analyze your data with a specific algorithm. + +Go to the Algo-providers page from the menu: + +

+Clear layout button +

+ +You will see the list of available algorithms: + +![add](./algo_providers_menu_3.png) + +Click on the algorithm you want to use. You will see the description of the algorithm and the inputs it needs: + +![add](./algo_providers_menu_4.png) + +Fill the inputs and click on the "Run" button: + +![add](./algo_providers_menu_5.png) + +The algorithm will be run and the results will be available in the "Experiments" tab: + +In the "Experiments" tab, you can see the results of the algorithm and you can add them to the analysis dashboard data as a new column: + +![add](./algo_providers_menu_6.png) + +Once the results are added to the analysis dashboard, you can analyze them like any other data. + +Learn more about: +- [The different integrated algorithms in DebiAI](./integratedAlgorithms.md). +- [How to add your own algorithms to DebiAI](./algoProviders/). +- [How to analyze data in DebiAI](../dashboard/) + diff --git a/documentation/customAlgorithms/integratedAlgorithms.md b/documentation/customAlgorithms/integratedAlgorithms.md new file mode 100644 index 0000000..5517be5 --- /dev/null +++ b/documentation/customAlgorithms/integratedAlgorithms.md @@ -0,0 +1,12 @@ +# DebiAI integrated Algorithms + +DebiAI comes with a set of integrated algorithms that you can use right away. +If you want to add your own algorithms, check the [Custom algorithms documentation](./README.md). If you want to check the the code of the integrated algorithms, you can find it [here](https://github.com/debiai/debiai/tree/main/debiaiServer/modules/algoProviders/integratedAlgoProvider/algorithms). If you are interested in a specific algorithm, [let us know](https://github.com/debiai/debiai/issues). + +## Classification Metric + +Calculates the classification error according to the ground truth and the predictions. Useful to evaluate the performance of a classification model. It basically calculates the number of misclassified samples. Finally, the algorithms returns a list of booleans that indicates True if the sample is misclassified and False otherwise. + +## Regression Metric + +Calculates the regression error according to the ground truth, the predictions and a ceil value. Useful to evaluate the performance of a regression model. It basically calculates the absolute difference between the ground truth and the predictions. Finally, the algorithms returns a list of booleans that indicates True if the error is above the ceil value. diff --git a/documentation/dashboard/algoProviders/menu.png b/documentation/customAlgorithms/menu.png similarity index 100% rename from documentation/dashboard/algoProviders/menu.png rename to documentation/customAlgorithms/menu.png diff --git a/documentation/dashboard/README.md b/documentation/dashboard/README.md index 72c39b4..2822cc5 100644 --- a/documentation/dashboard/README.md +++ b/documentation/dashboard/README.md @@ -107,7 +107,7 @@ Besides the widgets, the dashboard has several features that allow you to intera - [Saving a layout](./layouts/). You can save your current dashboard layout to be able to load it later. -- [Custom algorithms](./algoProviders/). You can create your own algorithms, use them with the data in the dashboard to generate new analyzable columns. +- [Custom algorithms](../customAlgorithms/). You can create your own algorithms, use them with the data in the dashboard to generate new analyzable columns. - [Exporting data](./dataExport/). You can export your data to other tools for annotation or further analysis purposes. diff --git a/documentation/dashboard/algoProviders/README.md b/documentation/dashboard/algoProviders/README.md deleted file mode 100644 index 4c5a6bf..0000000 --- a/documentation/dashboard/algoProviders/README.md +++ /dev/null @@ -1,96 +0,0 @@ -# Algo-providers, adding custom algorithms to DebiAI - -From the DebiAI analysis dashboard and with the analyzed data, you can use some algorithms that can generate metrics. Those generated results can be added as a new column into the analysis dashboard data and be used with the widgets like any other column. - -## How to use one algorithm - -Go to the Algo-providers page from the menu: - -

-Clear layout button -

- -You will see the list of available algorithms: - -![add](./algo_providers_menu_3.png) - -Click on the algorithm you want to use. You will see the description of the algorithm and the inputs it needs: - -![add](./algo_providers_menu_4.png) - -Fill the inputs and click on the "Run" button: - -![add](./algo_providers_menu_5.png) - -The algorithm will be run and the results will be available in the "Experiments" tab: - -In the "Experiments" tab, you can see the results of the algorithm and you can add them to the analysis dashboard data as a new column: - -![add](./algo_providers_menu_6.png) - -## Integrated algorithms - -DebiAI comes with a set of algorithms that can be used with the data in the dashboard. You can find the list of available algorithms in the [Integrated algorithms documentation](./integratedAlgorithms.md). - -## Custom algorithms - -DebiAI allows you to implement your own algorithms. This can be useful if you want to use one that is not available in DebiAI or that is specific to your use case. - -### Algorithms description - -You will need to describe your algorithm in a Json format and then create the implementation of your algorithm. After that, DebiAI will be able to understand your algorithm and run it. - -Here is, for example, the description of a simple moving average algorithm: - -```json -{ - "id": "moving_average", - "name": "Moving average", - "description": "Calculate the moving average of a data.", - "tags": ["calculations"], - "author": "DebiAI", - "version": "1.0.0", - "inputs": [ - { - "name": "data", - "description": "The data to calculate the moving average on.", - "type": "array", - "arrayType": "number", - "lengthMin": 1, - "lengthMax": 100000 - }, - { - "name": "periods", - "description": "The number of periods to calculate the moving average on.", - "type": "number", - "default": 3, - "min": 1, - "max": 100 - } - ], - "outputs": [ - { - "name": "moving_average", - "description": "The moving average of the data. Same length as the data", - "type": "array", - "arrayType": "number" - } - ] -} -``` - -As you can see, the input and output of the algorithm are described. This description is used by DebiAI to understand how to run the algorithm and how to display it in the dashboard and what kind of data it needs. - -To learn more about the algorithms descriptions, you can read the [Algorithm description documentation](https://github.com/debiai/algo-provider-python-template/blob/main/algo-api/README.md). - -### Add your own algorithm - -You can add your own algorithms to DebiAI in two ways: - -- [Algo-provider Python module](https://github.com/debiai/easy-algo-provider). This is the easiest way to add your own algorithms to DebiAI. You just have to define a Python function that implements your algorithm and the library will take care of the rest. - -- [Creating an Algo-provider service](./algoProviders.md). An algo-provider is a simple Web service that provides one or more algorithms. You can create your own algo-provider with any programming language, host it and provide the URL to DebiAI. - -- [Inserting Python code in DebiAI](./implementInBackend.md). You can insert Python code directly in the DebiAI backend. This is useful if you want to use an algorithm that you have created in Python, but you don't want to host it yourself. - -We are currently working on a way to add algorithms directly from the dashboard, [let us know](https://github.com/debiai/debiai/issues) if you are interested in this or any other feature. diff --git a/documentation/dashboard/algoProviders/algoProviders.md b/documentation/dashboard/algoProviders/algoProviders.md deleted file mode 100644 index 4e4929f..0000000 --- a/documentation/dashboard/algoProviders/algoProviders.md +++ /dev/null @@ -1,45 +0,0 @@ -# Creating an Algo-provider - -An algo provider is a service that you have to create that can respond to the algorithms requests of DebiAI. This service can be made in **any language**, can use **any kind algorithms** and can be hosted on **any platform** as long at the DebiAI algo-provider's API is respected. - -DebiAI will interact with your algo provider in two ways: - -- For getting the list of available algorithms -- For running an algorithm and getting the results - -The [algo-provider Python module](https://github.com/debiai/easy-algo-provider) starts a Fast API server that provides a REST API to interact with DebiAI. This is the easiest way to create an algo provider for DebiAI. - -## The API - -The Algo-providers API as been described with OpenAPI 3.0. - -- [Algo-providers API Swagger documentation](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/debiai/algo-provider-python-template/main/algo-api/OpenAPI/Algo_OpenAPI_V0.yaml) -- [Alg-providers API yaml file](https://github.com/debiai/algo-provider-python-template/blob/main/algo-api/OpenAPI/Algo_OpenAPI_V0.yaml). - -## Getting started - -To help you create your first algo provider, we have created an [Algo-provider Python template](https://github.com/debiai/algo-provider-python-template). You can use it as a starting point for your own algo provider. - -If you want to create an algo provider in another language, you just need to respect the [Algo-providers API](#the-api). - -You need help creating your algo provider? [Create an issue](https://github.com/debiai/debiai/issues) and we will help you. - -## Adding your algo provider to DebiAI - -Once you have created and deployed your algo provider, you can add it to DebiAI. - -To do so, go to the Algo-providers page from the menu: - -![menu](./menu.png) - -And click on the "Add a new algo provider" button: - -![add](./algo_providers_menu_1.png) - -You will need to provide the URL of your algo provider. This URL should be the root URL of your algo provider, for example: `https://my-algo-provider.com/`. - -![add](./algo_providers_menu_2.png) - -Once you have added your algo provider, you will be able to use the algorithms it provides in the Algorithms tab of the analysis dashboard: - -![add](./algo_providers_menu_3.png) diff --git a/documentation/dashboard/algoProviders/integratedAlgorithms.md b/documentation/dashboard/algoProviders/integratedAlgorithms.md deleted file mode 100644 index 2b31fe3..0000000 --- a/documentation/dashboard/algoProviders/integratedAlgorithms.md +++ /dev/null @@ -1,13 +0,0 @@ -# DebiAI integrated Algorithms - -DebiAI comes with a set of integrated algorithms that you can use right away. If you want to add your own algorithms, check the [Custom algorithms documentation](./README.md). - -If you want to check the the code of the integrated algorithms, you can find it [here](https://github.com/debiai/debiai/tree/main/debiaiServer/modules/algoProviders/integratedAlgoProvider/algorithms). - -If you are interested in a specific algorithm, [let us know](https://github.com/debiai/debiai/issues). - -## List of integrated algorithms - -- **Classification Metric**, Calculates the classification error according to the ground truth and the predictions. Useful to evaluate the performance of a classification model. It basically calculates the number of misclassified samples. Finally, the algorithms returns a list of booleans that indicates True if the sample is misclassified and False otherwise. - -- **Regression Metric**, Calculates the regression error according to the ground truth, the predictions and a ceil value. Useful to evaluate the performance of a regression model. It basically calculates the absolute difference between the ground truth and the predictions. Finally, the algorithms returns a list of booleans that indicates True if the error is above the ceil value.