<jupyter_start><jupyter_text>Data Attribute Recommendation - TechED 2020 INT260Getting started with the Python SDK for the Data Attribute Recommendation service.  Business ScenarioWe will consider a business scenario involving product master data. The creation and maintenance of this product master data requires the careful manual selection of the correct categories for a given product from a pre-defined hierarchy of product categories.In this workshop, we will explore how to automate this tedious manual task with the Data Attribute Recommendation service.  This workshop will cover:    * Data Upload* Model Training and Deployment* Inference Requests    We will work through a basic example of how to achieve these tasks using the [Python SDK for Data Attribute Recommendation](https://github.com/SAP/data-attribute-recommendation-python-sdk). *Note: if you are doing several runs of this notebook on a trial account, you may see errors stating 'The resource can no longer be used. Usage limit has been reached'. It can be beneficial to [clean up the service instance](Cleaning-up-a-service-instance) to free up limited trial resources acquired by an earlier run of the notebook. [Some limits](https://help.sap.com/viewer/105bcfd88921418e8c29b24a7a402ec3/SHIP/en-US/c03b561eea1744c9b9892b416037b99a.html) cannot be reset this way.*  Table of Contents* [Exercise 01.1](Exercise-01.1) - Installing the SDK and preparing the service key    * [Creating a service instance and key on BTP Trial](Creating-a-service-instance-and-key)    * [Installing the SDK](Installing-the-SDK)    * [Loading the service key into your Jupyter Notebook](Loading-the-service-key-into-your-Jupyter-Notebook)* [Exercise 01.2](Exercise-01.2) - Uploading the data* [Exercise 01.3](Exercise-01.3) - Training the model* [Exercise 01.4](Exercise-01.4) - Deploying the Model and predicting labels* [Resources](Resources) - Additional reading* [Cleaning up a service instance](Cleaning-up-a-service-instance) - Clean up all resources on the service instance* [Optional Exercises](Optional-Exercises) - Optional exercises  RequirementsSee the [README in the Github repository for this workshop](https://github.com/SAP-samples/teched2020-INT260/blob/master/exercises/ex1-DAR/README.md).  Exercise 01.1*Back to [table of contents](Table-of-Contents)*In exercise 01.1, we will install the SDK and prepare the service key.  Creating a service instance and key on BTP Trial Please log in to your trial account: https://cockpit.eu10.hana.ondemand.com/trial/In the your global account screen, go to the "Boosters" tab:![trial_booster.png](attachment:trial_booster.png)*Boosters are only available on the Trial landscape. If you are using a production environment, please follow this tutorial to manually [create a service instance and a service key](https://developers.sap.com/tutorials/cp-aibus-dar-service-instance.html)*. In the Boosters tab, enter "Data Attribute Recommendation" into the search box. Then, select theservice tile from the search results:     ![trial_locate_dar_booster.png](attachment:trial_locate_dar_booster.png) The resulting screen shows details of the booster pack. Here, click the "Start" button and wait a few seconds.![trial_start_booster.png](attachment:trial_start_booster.png) Once the booster is finished, click the "go to Service Key" link to obtain your service key.![trial_booster_finished.png](attachment:trial_booster_finished.png) Finally, download the key and save it to disk.![trial_download_key.png](attachment:trial_download_key.png)  Installing the SDK The Data Attribute Recommendation SDK is available from the Python package repository. It can be installed with the standard `pip` tool:<jupyter_code>! pip install data-attribute-recommendation-sdk<jupyter_output><empty_output><jupyter_text>*Note: If you are not using a Jupyter notebook, but instead a regular Python development environment, we recommend using a Python virtual environment to set up your development environment. Please see [the dedicated tutorial to learn how to install the SDK inside a Python virtual environment](https://developers.sap.com/tutorials/cp-aibus-dar-sdk-setup.html).*  Loading the service key into your Jupyter Notebook Once you downloaded the service key from the Cockpit, upload it to your notebook environment. The service key must be uploaded to same directory where the `teched2020-INT260_Data_Attribute_Recommendation.ipynb` is stored.We first navigate to the file browser in Jupyter. On the top of your Jupyter notebook, right-click on the Jupyter logo and open in a new tab.![service_key_main_jupyter_page.png](attachment:service_key_main_jupyter_page.png) **In the file browser, navigate to the directory where the `teched2020-INT260_Data_Attribute_Recommendation.ipynb` notebook file is stored. The service key must reside next to this file.**In the Jupyter file browser, click the **Upload** button (1). In the file selection dialog that opens, select the `defaultKey_*.json` file you downloaded previously from the SAP Cloud Platform Cockpit. Rename the file to `key.json`. Confirm the upload by clicking on the second **Upload** button (2).![service_key_upload.png](attachment:service_key_upload.png) The service key contains your credentials to access the service. Please treat this as carefully as you would treat any password. We keep the service key as a separate file outside this notebook to avoid leaking the secret credentials.The service key is a JSON file. We will load this file once and use the credentials throughout this workshop.<jupyter_code># First, set up logging so we can see the actions performed by the SDK behind the scenes
import logging
import sys

logging.basicConfig(level=logging.INFO, stream=sys.stdout)

from pprint import pprint # for nicer output formatting
import json
import os

if not os.path.exists("key.json"):
    msg = "key.json is not found. Please follow instructions above to create a service key of"
    msg += " Data Attribute Recommendation. Then, upload it into the same directory where"
    msg += " this notebook is saved."
    print(msg)
    raise ValueError(msg)

with open("key.json") as file_handle:
    key = file_handle.read()
    SERVICE_KEY = json.loads(key)<jupyter_output><empty_output><jupyter_text>Summary Exercise 01.1In exercise 01.1, we have covered the following topics:* How to install the Python SDK for Data Attribute Recommendation* How to obtain a service key for the Data Attribute Recommendation service  Exercise 01.2*Back to [table of contents](Table-of-Contents)**To perform this exercise, you need to execute the code in all previous exercises.*In exercise 01.2, we will upload our demo dataset to the service.  The Dataset  Obtaining the Data The dataset we use in this workshop is a CSV file containing product master data. The original data was released by BestBuy, a retail company, under an [open license](https://github.com/SAP-samples/data-attribute-recommendation-postman-tutorial-sampledata-and-license). This makes it ideal for first experiments with the Data Attribute Recommendation service. The dataset can be downloaded directly from Github using the following command:<jupyter_code>! wget -O bestBuy.csv "https://raw.githubusercontent.com/SAP-samples/data-attribute-recommendation-postman-tutorial-sample/master/Tutorial_Example_Dataset.csv"
# If you receive a "command not found" error (i.e. on Windows), try curl instead of wget:
# ! curl -o bestBuy.csv "https://raw.githubusercontent.com/SAP-samples/data-attribute-recommendation-postman-tutorial-sample/master/Tutorial_Example_Dataset.csv"<jupyter_output><empty_output><jupyter_text>Let's inspect the data:<jupyter_code># if you are experiencing an import error here, run the following in a new cell:
# ! pip install pandas
import pandas as pd

df = pd.read_csv("bestBuy.csv")
df.head(5)
print()
print(f"Data has {df.shape[0]} rows and {df.shape[1]} columns.")<jupyter_output><empty_output><jupyter_text>The CSV contains the several products. For each product, the description, the manufacturer and the price are given. Additionally, three levels of the products hierarchy are given.The first product, a set of AAA batteries, is located in the following place in the product hierarchy:```level1_category:         Connected Home & Housewares                                      |level2_category:                  Housewares                                      |level3_category:              Household Batteries``` We will use the Data Attribute Recommendation service to predict the categories for a given product based on its **description**, **manufacturer** and **price**.  Creating the DatasetSchema We first have to describe the shape of our data by creating a DatasetSchema. This schema informs the service about the individual column types found in the CSV. We also describe which are the target columns used for training. These columns will be later predicted. In our case, these are the three category columns.The service currently supports three column types: **text**, **category** and **number**. For prediction, only **category** is currently supported.A DatasetSchema for the BestBuy dataset looks as follows:```json{    "features": [        {"label": "manufacturer", "type": "CATEGORY"},        {"label": "description", "type": "TEXT"},        {"label": "price", "type": "NUMBER"}    ],    "labels": [        {"label": "level1_category", "type": "CATEGORY"},        {"label": "level2_category", "type": "CATEGORY"},        {"label": "level3_category", "type": "CATEGORY"}    ],    "name": "bestbuy-category-prediction",}```We will now upload this DatasetSchema to the Data Attribute Recommendation service. The SDK provides the[`DataManagerClient.create_dataset_schema()`](https://data-attribute-recommendation-python-sdk.readthedocs.io/en/latest/api.htmlsap.aibus.dar.client.data_manager_client.DataManagerClient.create_dataset_schema) method for this purpose.<jupyter_code>from sap.aibus.dar.client.data_manager_client import DataManagerClient

dataset_schema = {
    "features": [
        {"label": "manufacturer", "type": "CATEGORY"},
        {"label": "description", "type": "TEXT"},
        {"label": "price", "type": "NUMBER"}
    ],
    "labels": [
        {"label": "level1_category", "type": "CATEGORY"},
        {"label": "level2_category", "type": "CATEGORY"},
        {"label": "level3_category", "type": "CATEGORY"}
    ],
    "name": "bestbuy-category-prediction",
}


data_manager = DataManagerClient.construct_from_service_key(SERVICE_KEY)
response = data_manager.create_dataset_schema(dataset_schema)
dataset_schema_id = response["id"]

print()
print("DatasetSchema created:")

pprint(response)

print()
print(f"DatasetSchema ID: {dataset_schema_id}")<jupyter_output><empty_output><jupyter_text>The API responds with the newly created DatasetSchema resource. The service assigned an ID to the schema. We save this ID in a variable, as we will need it when we upload the data.  Uploading the Data to the service The [`DataManagerClient`](https://data-attribute-recommendation-python-sdk.readthedocs.io/en/latest/api.htmlsap.aibus.dar.client.data_manager_client.DataManagerClient) class is also responsible for uploading data to the service. This data must fit to an existing DatasetSchema. After uploading the data, the service will validate the Dataset against the DataSetSchema in a background process. The data must be a CSV file which can optionally be `gzip` compressed.We will now upload our `bestBuy.csv` file, using the DatasetSchema which we created earlier.Data upload is a two-step process. We first create the Dataset using [`DataManagerClient.create_dataset()`](https://data-attribute-recommendation-python-sdk.readthedocs.io/en/latest/api.htmlsap.aibus.dar.client.data_manager_client.DataManagerClient.create_dataset). Then we can upload data to the Dataset using the [`DataManagerClient.upload_data_to_dataset()`](https://data-attribute-recommendation-python-sdk.readthedocs.io/en/latest/api.htmlsap.aibus.dar.client.data_manager_client.DataManagerClient.upload_data_to_dataset) method.<jupyter_code>dataset_resource = data_manager.create_dataset("my-bestbuy-dataset", dataset_schema_id)
dataset_id = dataset_resource["id"]

print()
print("Dataset created:")

pprint(dataset_resource)

print()
print(f"Dataset ID: {dataset_id}")
# Compress file first for a faster upload
! gzip -9 -c bestBuy.csv > bestBuy.csv.gz<jupyter_output><empty_output><jupyter_text>Note that the data upload can take a few minutes. Please do not restart the process while the cell is still running.<jupyter_code># Open in binary mode.
with open('bestBuy.csv.gz', 'rb') as file_handle:
    dataset_resource = data_manager.upload_data_to_dataset(dataset_id, file_handle)

print()
print("Dataset after data upload:")
print()
pprint(dataset_resource)<jupyter_output><empty_output><jupyter_text>Note that the Dataset status changed from `NO_DATA` to `VALIDATING`.Dataset validation is a background process. The status will eventually change from `VALIDATING` to `SUCCEEDED`.The SDK provides the [`DataManagerClient.wait_for_dataset_validation()`](https://data-attribute-recommendation-python-sdk.readthedocs.io/en/latest/api.htmlsap.aibus.dar.client.data_manager_client.DataManagerClient.wait_for_dataset_validation) method to poll for the Dataset validation.<jupyter_code>dataset_resource = data_manager.wait_for_dataset_validation(dataset_id)

print()
print("Dataset after validation has finished:")

print()
pprint(dataset_resource)<jupyter_output><empty_output><jupyter_text>If the status is `FAILED` instead of `SUCCEEDED`, then the `validationMessage` will contain details about the validation failure. To better understand the Dataset lifecycle, refer to the [corresponding document on help.sap.com](https://help.sap.com/viewer/105bcfd88921418e8c29b24a7a402ec3/SHIP/en-US/a9b7429687a04e769dbc7955c6c44265.html).  Summary Exercise 01.2In exercise 01.2, we have covered the following topics:* How to create a DatasetSchema* How to upload a Dataset to the serviceYou can find optional exercises related to exercise 01.2 [below](Optional-Exercises-for-01.2).  Exercise 01.3*Back to [table of contents](Table-of-Contents)**To perform this exercise, you need to execute the code in all previous exercises.*In exercise 01.3, we will train the model.  Training the Model The Dataset is now uploaded and has been validated successfully by the service.To train a machine learning model, we first need to select the correct model template.  Selecting the right ModelTemplateThe Data Attribute Recommendation service currently supports two different ModelTemplates:| ID                                   | Name                  | Description                                                               ||--------------------------------------|---------------------------|---------------------------------------------------------------------------|| d7810207-ca31-4d4d-9b5a-841a644fd81f | **Hierarchical template** | Recommended for the prediction of multiple classes that form a hierarchy. || 223abe0f-3b52-446f-9273-f3ca39619d2c | **Generic template**      | Generic neural network for multi-label, multi-class classification.       || 188df8b2-795a-48c1-8297-37f37b25ea00 | **AutoML template**      | Finds the [best traditional machine learning model out of several traditional algorithms](https://blogs.sap.com/2021/04/28/how-does-automl-works-in-data-attribute-recommendation/). Single label only. |We are building a model to predict product hierarchies. The **Hierarchical Template** is correct for this scenario. In this template, the first label in the DatasetSchema is considered the top-level category. Each subsequent label is considered to be further down in the hierarchy. Coming back to our example DatasetSchema:```json{ "labels": [        {"label": "level1_category", "type": "CATEGORY"},        {"label": "level2_category", "type": "CATEGORY"},        {"label": "level3_category", "type": "CATEGORY"}    ]}```The first defined label is `level1_category`, which is given more weight during training than `level3_category`.Refer to the [official documentation on ModelTemplates](https://help.sap.com/viewer/105bcfd88921418e8c29b24a7a402ec3/SHIP/en-US/1e76e8c636974a06967552c05d40e066.html) to learn more. Additional model templates may be added over time, so check back regularly.  Starting the training When working with models, we use the [`ModelManagerClient`](https://data-attribute-recommendation-python-sdk.readthedocs.io/en/latest/api.htmlsap.aibus.dar.client.model_manager_client.ModelManagerClient) class.To start the training, we need the IDs of the dataset and the desired model template. We also have to provide a name for the model.The [`ModelManagerClient.create_job()`](https://data-attribute-recommendation-python-sdk.readthedocs.io/en/latest/api.htmlsap.aibus.dar.client.model_manager_client.ModelManagerClient.create_job) method launches the training Job.*Only one model of a given name can exist. If you receive a message stating 'The model name specified is already in use', you either have to remove the job and its associated model first or you have to change the `model_name` variable name below. You can also [clean up the entire service instance](Cleaning-up-a-service-instance).*<jupyter_code>from sap.aibus.dar.client.model_manager_client import ModelManagerClient
from sap.aibus.dar.client.exceptions import DARHTTPException

model_manager = ModelManagerClient.construct_from_service_key(SERVICE_KEY)

model_template_id = "d7810207-ca31-4d4d-9b5a-841a644fd81f" # hierarchical template
model_name = "bestbuy-hierarchy-model"

job_resource = model_manager.create_job(model_name, dataset_id, model_template_id)
job_id = job_resource['id']

print()
print("Job resource:")
print()

pprint(job_resource)

print()
print(f"ID of submitted Job: {job_id}")<jupyter_output><empty_output><jupyter_text>The job is now running in the background. Similar to the DatasetValidation, we have to poll the job until it succeeds.The SDK provides the [`ModelManagerClient.wait_for_job()`](https://data-attribute-recommendation-python-sdk.readthedocs.io/en/latest/api.htmlsap.aibus.dar.client.model_manager_client.ModelManagerClient.wait_for_job) method:<jupyter_code>job_resource = model_manager.wait_for_job(job_id)

print()

print("Job resource after training is finished:")

pprint(job_resource)<jupyter_output><empty_output><jupyter_text>To better understand the Training Job lifecycle, see the [corresponding document on help.sap.com](https://help.sap.com/viewer/105bcfd88921418e8c29b24a7a402ec3/SHIP/en-US/0fc40aa077ce4c708c1e5bfc875aa3be.html).  IntermissionThe model training will take between 5 and 10 minutes.In the meantime, we can explore the available [resources](Resources) for both the service and the SDK.  Inspecting the ModelOnce the training job is finished successfully, we can inspect the model using [`ModelManagerClient.read_model_by_name()`](https://data-attribute-recommendation-python-sdk.readthedocs.io/en/latest/api.htmlsap.aibus.dar.client.model_manager_client.ModelManagerClient.read_model_by_name).<jupyter_code>model_resource = model_manager.read_model_by_name(model_name)

print()
pprint(model_resource)<jupyter_output><empty_output><jupyter_text>In the model resource, the `validationResult` key provides information about model performance. You can also use these metrics to compare performance of different [ModelTemplates](Selecting-the-right-ModelTemplate) or different datasets.  Summary Exercise 01.3In exercise 01.3, we have covered the following topics:* How to select the appropriate ModelTemplate* How to train a Model from a previously uploaded DatasetYou can find optional exercises related to exercise 01.3 [below](Optional-Exercises-for-01.3).  Exercise 01.4*Back to [table of contents](Table-of-Contents)**To perform this exercise, you need to execute the code in all previous exercises.*In exercise 01.4, we will deploy the model and predict labels for some unlabeled data.  Deploying the Model The training job has finished and the model is ready to be deployed. By deploying the model, we create a server process in the background on the Data Attribute Recommendation service which will serve inference requests.In the SDK, the [`ModelManagerClient.create_deployment()`](https://data-attribute-recommendation-python-sdk.readthedocs.io/en/latest/api.htmlmodule-sap.aibus.dar.client.model_manager_client) method lets us create a Deployment.<jupyter_code>deployment_resource =  model_manager.create_deployment(model_name)
deployment_id = deployment_resource["id"]

print()
print("Deployment resource:")
print()

pprint(deployment_resource)

print(f"Deployment ID: {deployment_id}")<jupyter_output><empty_output><jupyter_text>*Note: if you are using a trial account and you see errors such as 'The resource can no longer be used. Usage limit has been reached', consider [cleaning up the service instance](Cleaning-up-a-service-instance) to free up limited trial resources.* Similar to the data upload and the training job, model deployment is an asynchronous process. We have to poll the API until the Deployment is in status `SUCCEEDED`. The SDK provides the [`ModelManagerClient.wait_for_deployment()`](https://data-attribute-recommendation-python-sdk.readthedocs.io/en/latest/api.htmlsap.aibus.dar.client.model_manager_client.ModelManagerClient.wait_for_deployment) for this purposes.<jupyter_code>deployment_resource = model_manager.wait_for_deployment(deployment_id)

print()
print("Finished deployment resource:")
print()

pprint(deployment_resource)<jupyter_output><empty_output><jupyter_text>Once the Deployment is in status `SUCCEEDED`, we can run inference requests. To better understand the Deployment lifecycle, see the [corresponding document on help.sap.com](https://help.sap.com/viewer/105bcfd88921418e8c29b24a7a402ec3/SHIP/en-US/f473b5b19a3b469e94c40eb27623b4f0.html). *For trial users: the deployment will be stopped after 8 hours. You can restart it by deleting the deployment and creating a new one for your model. The [`ModelManagerClient.ensure_deployment_exists()`](https://help.sap.com/viewer/105bcfd88921418e8c29b24a7a402ec3/SHIP/en-US/c03b561eea1744c9b9892b416037b99a.html) method will delete and re-create automatically. Then, you need to poll until the deployment is succeeded using [`ModelManagerClient.wait_for_deployment()`](https://data-attribute-recommendation-python-sdk.readthedocs.io/en/latest/api.htmlsap.aibus.dar.client.model_manager_client.ModelManagerClient.wait_for_deployment) as above.*  Executing Inference requests With a single inference request, we can send up to 50 objects to the service to predict the labels. The data send to the service must match the `features` section of the DatasetSchema created earlier. The `labels` defined inside of the DatasetSchema will be predicted for each object and returned as a response to the request.In the SDK, the [`InferenceClient.create_inference_request()`](https://data-attribute-recommendation-python-sdk.readthedocs.io/en/latest/api.htmlsap.aibus.dar.client.inference_client.InferenceClient.create_inference_request) method handles submission of inference requests.<jupyter_code>from sap.aibus.dar.client.inference_client import InferenceClient

inference = InferenceClient.construct_from_service_key(SERVICE_KEY)

objects_to_be_classified = [
    {
        "features": [
            {"name": "manufacturer", "value": "Energizer"},
            {"name": "description", "value": "Alkaline batteries; 1.5V"},
            {"name": "price", "value":  "5.99"},
        ],
    },
]

inference_response = inference.create_inference_request(model_name, objects_to_be_classified)

print()
print("Inference request processed. Response:")
print()
pprint(inference_response)<jupyter_output><empty_output><jupyter_text>*Note: For trial accounts, you only have a limited number of objects which you can classify.* You can also try to come up with your own example:<jupyter_code>my_own_items = [
    {
        "features": [
            {"name": "manufacturer", "value": "EDIT THIS"},
            {"name": "description", "value": "EDIT THIS"},
            {"name": "price", "value":  "0.00"},
        ],
    },
]

inference_response = inference.create_inference_request(model_name, my_own_items)

print()
print("Inference request processed. Response:")
print()
pprint(inference_response)<jupyter_output><empty_output><jupyter_text>You can also classify multiple objects at once. For each object, the `top_n` parameter determines how many predictions are returned.<jupyter_code>objects_to_be_classified = [
    {
        "objectId": "optional-identifier-1",
        "features": [
            {"name": "manufacturer", "value": "Energizer"},
            {"name": "description", "value": "Alkaline batteries; 1.5V"},
            {"name": "price", "value":  "5.99"},
        ],
    },
    {
        "objectId": "optional-identifier-2",
        "features": [
            {"name": "manufacturer", "value": "Eidos"},
            {"name": "description", "value": "Unravel a grim conspiracy at the brink of Revolution"},
            {"name": "price", "value":  "19.99"},
        ],
    },
    {
        "objectId": "optional-identifier-3",
        "features": [
            {"name": "manufacturer", "value": "Cadac"},
            {"name": "description", "value": "CADAC Grill Plate for Safari Chef Grills: 12\""
                                             + "cooking surface; designed for use with Safari Chef grills;"
                                             + "105 sq. in. cooking surface; PTFE nonstick coating;"
                                             + " 2 grill surfaces"
            },
            {"name": "price", "value":  "39.99"},
        ],
    }
]


inference_response = inference.create_inference_request(model_name, objects_to_be_classified, top_n=3)

print()
print("Inference request processed. Response:")
print()
pprint(inference_response)<jupyter_output><empty_output><jupyter_text>We can see that the service now returns the `n-best` predictions for each label as indicated by the `top_n` parameter.In some cases, the predicted category has the special value `nan`. In the `bestBuy.csv` data set, not all records have the full set of three categories. Some records only have a top-level category. The model learns this fact from the data and will occasionally suggest that a record should not have a category.<jupyter_code># Inspect all video games with just a top-level category entry
video_games = df[df['level1_category'] == 'Video Games']
video_games.loc[df['level2_category'].isna() & df['level3_category'].isna()].head(5)<jupyter_output><empty_output><jupyter_text>To learn how to execute inference calls without the SDK just using the underlying RESTful API, see [Inference without the SDK](Inference-without-the-SDK).  Summary Exercise 01.4In exercise 01.4, we have covered the following topics:* How to deploy a previously trained model* How to execute inference requests against a deployed modelYou can find optional exercises related to exercise 01.4 [below](Optional-Exercises-for-01.4).  Wrapping upIn this workshop, we looked into the following topics:* Installation of the Python SDK for Data Attribute Recommendation* Modelling data with a DatasetSchema* Uploading data into a Dataset* Training a model* Predicting labels for unlabelled dataUsing these tools, we are able to solve the problem of missing Master Data attributes starting from just a CSV file containing training data.Feel free to revisit the workshop materials at any time. The [resources](Resources) section below contains additional reading.If you would like to explore the additional capabilities of the SDK, visit the [optional exercises](Optional-Exercises) below.  Cleanup During the course of the workshop, we have created several resources on the Data Attribute Recommendation Service:* DatasetSchema* Dataset* Job* Model* DeploymentThe SDK provides several methods to delete these resources. Note that there are dependencies between objects: you cannot delete a Dataset without deleting the Model beforehand.You will need to set `CLEANUP_SESSION = True` below to execute the cleanup.<jupyter_code># Clean up all resources created earlier

CLEANUP_SESSION = False

def cleanup_session():
    model_manager.delete_deployment_by_id(deployment_id) # this can take a few seconds
    model_manager.delete_model_by_name(model_name)
    model_manager.delete_job_by_id(job_id)

    data_manager.delete_dataset_by_id(dataset_id)
    data_manager.delete_dataset_schema_by_id(dataset_schema_id)
    print("DONE cleaning up!")

if CLEANUP_SESSION:
    print("Cleaning up resources generated in this session.")
    cleanup_session()
else:
    print("Not cleaning up. Set 'CLEANUP_SESSION = True' above and run again!")<jupyter_output><empty_output><jupyter_text>Resources*Back to [table of contents](Table-of-Contents)* SDK Resources* [SDK source code on Github](https://github.com/SAP/data-attribute-recommendation-python-sdk)* [SDK documentation](https://data-attribute-recommendation-python-sdk.readthedocs.io/en/latest/)* [How to obtain support](https://github.com/SAP/data-attribute-recommendation-python-sdk/blob/master/README.mdhow-to-obtain-support)* [Tutorials: Classify Data Records with the SDK for Data Attribute Recommendation](https://developers.sap.com/group.cp-aibus-data-attribute-sdk.html) Data Attribute Recommendation* [SAP Help Portal](https://help.sap.com/viewer/product/Data_Attribute_Recommendation/SHIP/en-US)* [API Reference](https://help.sap.com/viewer/105bcfd88921418e8c29b24a7a402ec3/SHIP/en-US/b45cf9b24fd042d082c16191aa938c8d.html)* [Tutorials using Postman - interact with the service RESTful API directly](https://developers.sap.com/mission.cp-aibus-data-attribute.html)* [Trial Account Limits](https://help.sap.com/viewer/105bcfd88921418e8c29b24a7a402ec3/SHIP/en-US/c03b561eea1744c9b9892b416037b99a.html)* [Metering and Pricing](https://help.sap.com/viewer/105bcfd88921418e8c29b24a7a402ec3/SHIP/en-US/1e093326a2764c298759fcb92c5b0500.html)  Addendum  Inference without the SDK*Back to [table of contents](Table-of-Contents)* The Data Attribute Service exposes a RESTful API. The SDK we use in this workshop uses this API to interact with the DAR service.For custom integration, you can implement your own client for the API. The tutorial "[Use Machine Learning to Classify Data Records]" is a great way to explore the Data Attribute Recommendation API with the Postman REST client. Beyond the tutorial, the [API Reference] is a comprehensive documentation of the RESTful interface.[Use Machine Learning to Classify Data Records]: https://developers.sap.com/mission.cp-aibus-data-attribute.html[API Reference]: https://help.sap.com/viewer/105bcfd88921418e8c29b24a7a402ec3/SHIP/en-US/b45cf9b24fd042d082c16191aa938c8d.htmlTo demonstrate the underlying API, the next example uses the `curl` command line tool to perform an inference request against the Inference API.The example uses the `jq` command to extract the credentials from the service. The authentication token is retrieved from the `uaa_url` and then used for the inference request.<jupyter_code># If the following example gives you errors that the jq or curl commands cannot be found,
# you may be able to install them from conda by uncommenting one of the lines below:
#%conda install -q jq
#%conda install -q curl
%%bash -s "$model_name" # Pass the python model_name variable as the first argument to shell script

model_name=$1

echo "Model: $model_name"

key=$(cat key.json)
url=$(echo $key | jq -r .url)
uaa_url=$(echo $key | jq -r .uaa.url)
clientid=$(echo $key | jq -r .uaa.clientid)
clientsecret=$(echo $key | jq -r .uaa.clientsecret)

echo "Service URL: $url"

token_url=${uaa_url}/oauth/token?grant_type=client_credentials

echo "Obtaining token with clientid $clientid from $token_url"

bearer_token=$(curl \
                --silent --show-error \
                --user $clientid:$clientsecret \
                $token_url \
                | jq -r .access_token
             )

inference_url=${url}/inference/api/v3/models/${model_name}/versions/1

echo "Running inference request against endpoint $inference_url"

echo ""

# We pass the token in the Authorization header.
# The payload for the inference request is passed as
# the body of the POST request below.
# The output of the curl command is piped through `jq`
# for pretty-printing
curl \
    --silent --show-error \
    --header "Authorization: Bearer ${bearer_token}" \
    --header "Content-Type: application/json" \
    -XPOST \
    ${inference_url} \
    -d '{
          "objects": [
            {
              "features": [
                {
                  "name": "manufacturer",
                  "value": "Energizer"
                },
                {
                  "name": "description",
                  "value": "Alkaline batteries; 1.5V"
                },
                {
                  "name": "price",
                  "value": "5.99"
                }
              ]
            }
          ]
        }' | jq<jupyter_output><empty_output><jupyter_text>Cleaning up a service instance*Back to [table of contents](Table-of-Contents)*To clean all data on the service instance, you can run the following snippet. The code is self-contained and does not require you to execute any of the cells above. However, you will need to have the `key.json` containing a service key in place.You will need to set `CLEANUP_EVERYTHING = True` below to execute the cleanup.**NOTE: This will delete all data on the service instance!**<jupyter_code>CLEANUP_EVERYTHING = False

def cleanup_everything():
    import logging
    import sys

    logging.basicConfig(level=logging.INFO, stream=sys.stdout)

    import json
    import os

    if not os.path.exists("key.json"):
        msg = "key.json is not found. Please follow instructions above to create a service key of"
        msg += " Data Attribute Recommendation. Then, upload it into the same directory where"
        msg += " this notebook is saved."
        print(msg)
        raise ValueError(msg)

    with open("key.json") as file_handle:
        key = file_handle.read()
        SERVICE_KEY = json.loads(key)

    from sap.aibus.dar.client.model_manager_client import ModelManagerClient

    model_manager = ModelManagerClient.construct_from_service_key(SERVICE_KEY)

    for deployment in model_manager.read_deployment_collection()["deployments"]:
        model_manager.delete_deployment_by_id(deployment["id"])

    for model in model_manager.read_model_collection()["models"]:
        model_manager.delete_model_by_name(model["name"])

    for job in model_manager.read_job_collection()["jobs"]:
        model_manager.delete_job_by_id(job["id"])

    from sap.aibus.dar.client.data_manager_client import DataManagerClient

    data_manager = DataManagerClient.construct_from_service_key(SERVICE_KEY)

    for dataset in data_manager.read_dataset_collection()["datasets"]:
        data_manager.delete_dataset_by_id(dataset["id"])

    for dataset_schema in data_manager.read_dataset_schema_collection()["datasetSchemas"]:
        data_manager.delete_dataset_schema_by_id(dataset_schema["id"])
        
    print("Cleanup done!")

if CLEANUP_EVERYTHING:
    print("Cleaning up all resources in this service instance.")
    cleanup_everything()
else:
    print("Not cleaning up. Set 'CLEANUP_EVERYTHING = True' above and run again.")<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09477685485006335, 'fraction_numerical': 0.019963395748275378, 'mean_word_length': 4.5930708661417325, 'pattern_counts': {'":': 83, '<': 81, '<?xml version=': 0, '>': 82, 'https://': 39, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 18, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '20', 'dir': 'jupyter-structured-clean-dedup', 'id': '913', 'license': 'Apache-2.0', 'n_tokens_mistral': 10577, 'n_tokens_neox': 9897, 'n_words': 3363, 'path': 'exercises/ex1-DAR/teched2020-INT260_Data_Attribute_Recommendation.ipynb', 'repo_name': 'SAP-samples/teched2020-INT260', 'size': '35515'}