|
| 1 | +# Connecting watsonx Assistant to External Database |
| 2 | + |
| 3 | +## Integrating with data source services on Microsoft Azure |
| 4 | + |
| 5 | +Please refer to the following [link](https://www.ibm.com/docs/en/watsonx/saas?topic=platforms-integrating-data-source-services-azure){ target=\_blank}. |
| 6 | + |
| 7 | +## Integrating with Db2 Database (example) |
| 8 | + |
| 9 | +### Retrieve Database Service Credentials |
| 10 | + |
| 11 | +First, you will need to retrieve service credentials from your Db2 instance. Go to your Db2 instance, select the **Service credentials** page, and click on the **New credential** button in the top right. |
| 12 | + |
| 13 | + |
| 14 | + |
| 15 | +Name your credentials as you like, select **Manager** as the role, and click **Add**. |
| 16 | + |
| 17 | + |
| 18 | + |
| 19 | +!!! note "Credentials to Note" |
| 20 | + |
| 21 | + You will need some of the credentials that you've just created later on in the article. Open up the service credentials and note the **database**, **hostname**, **port**, **username**, and **password**. |
| 22 | + |
| 23 | +### Create Table in Db2 |
| 24 | + |
| 25 | +Navigate to the **Manage** section from the menu on the left and click on the **Go to UI** button. |
| 26 | + |
| 27 | + |
| 28 | + |
| 29 | +Click on the **SQL** tab and paste the SQL statement from below. Click **Run all**. |
| 30 | + |
| 31 | + |
| 32 | + |
| 33 | +```mysql linenums="1" |
| 34 | +CREATE TABLE USER_INFO ( |
| 35 | + NAME VARCHAR(255), |
| 36 | + EMAIL VARCHAR(255), |
| 37 | + ADDRESS VARCHAR(255) |
| 38 | +); |
| 39 | +``` |
| 40 | + |
| 41 | +!!! note "Table Info" |
| 42 | + |
| 43 | + This statement creates a table called **USER_INFO** with 3 columns: **NAME**, **EMAIL**, and **ADDRESS**. |
| 44 | + |
| 45 | +Next, navigate to the **Data** tab from the left hand menu. From there, select **Tables** from the menu on top and select the available schema. You should see the **USER_INFO** table and when you click on that you should see the table definition with the columns listed as well. Once we send data to the database, you will be able to view the data by coming back to this page and clicking the **View data** button. |
| 46 | + |
| 47 | + |
| 48 | + |
| 49 | +### Host a Public Endpoint for Code Snippet |
| 50 | + |
| 51 | +We will need code for the actual action to send our data to the database and an endpoint for our watsonx Assistant to hit. Use a tool that hosts your code and exposes a public endpoint. You can use the code from below. Make sure to update your database credentials on lines 7-11 and the schema on line 28. |
| 52 | + |
| 53 | +```py linenums="1" |
| 54 | +import sys |
| 55 | +import json |
| 56 | +import os, ibm_db, ibm_db_dbi |
| 57 | +import pandas as pd |
| 58 | +import requests |
| 59 | +def main(params): |
| 60 | + dsn_database = "xxxxxxx" # e.g. "MORTGAGE" |
| 61 | + dsn_uid = "xxxxxxx" # e.g. "dash104434" |
| 62 | + dsn_pwd = "xxxxxxx" # e.g. "7dBZ3jWt9xN6$o0JiX!m" |
| 63 | + dsn_hostname = "xxxxxxx" # e.g. "Use the same IP as Web Console" |
| 64 | + dsn_port = "xxxxxxx" # e.g. "50000" |
| 65 | + dsn_protocol = "TCPIP" # i.e. "TCPIP" |
| 66 | + dsn_driver = "IBM DB2 ODBC DRIVER" # Don't change |
| 67 | + dsn = ("DRIVER={{IBM DB2 ODBC DRIVER}};" "DATABASE={0};" "HOSTNAME={1};" "PORT={2};" "PROTOCOL=TCPIP;" "UID={3};" "PWD={4};SECURITY=SSL").format(dsn_database, dsn_hostname, dsn_port, dsn_uid, dsn_pwd) |
| 68 | + |
| 69 | + options = { ibm_db.SQL_ATTR_AUTOCOMMIT: ibm_db.SQL_AUTOCOMMIT_ON } |
| 70 | + connection = ibm_db_dbi.connect(dsn, dsn_uid, dsn_pwd, dsn_hostname, dsn_database, options) |
| 71 | + cursor = connection.cursor() |
| 72 | + |
| 73 | + columns = ['NAME','EMAIL','ADDRESS'] |
| 74 | + |
| 75 | + # The value you want to insert |
| 76 | + name = params['name'] |
| 77 | + email = params['email'] |
| 78 | + address = params['address'] |
| 79 | + columns_str = ', '.join(columns) |
| 80 | + placeholders = ', '.join(['?'] * len(columns)) |
| 81 | + insertSQL = f'INSERT INTO XXXXXX.USER_INFO ({columns_str}) VALUES ({placeholders});' |
| 82 | + |
| 83 | + # Executing the SQL query with the value to insert |
| 84 | + cursor.execute(insertSQL, (name, email, address)) |
| 85 | + # Committing the transaction |
| 86 | + |
| 87 | + connection.commit() |
| 88 | + # Closing the cursor and connection |
| 89 | + |
| 90 | + cursor.close() |
| 91 | +``` |
| 92 | + |
| 93 | +This action takes 3 parameters - name, email, and address - and sends them to the database. |
| 94 | + |
| 95 | +Once you've saved this code snippet and found the public endpoint, take note of the endpoint as we will need this for later. |
| 96 | + |
| 97 | +### Create OpenAPI Document |
| 98 | + |
| 99 | +An OpenAPI document describes an API in terms of paths and operations. In OpenAPI terms, paths are endpoints (resources), such as a hotel reservation or a customer record, that your API exposes, and operations are the HTTP methods used to manipulate these paths, such as GET, POST, or DELETE. |
| 100 | + |
| 101 | +You can use the [Swagger Editor](https://editor.swagger.io/){ target=\_blank} to create and modify your OpenAPI document. |
| 102 | + |
| 103 | +You can use the following block of sample OpenAPI document in your Swagger Editor. I have provided it in a .json format since watsonx Assistant requires an OpenAPI document in .json format to build a custom integration. |
| 104 | + |
| 105 | +```json linenums="1" |
| 106 | +{ |
| 107 | + "openapi": "3.0.3", |
| 108 | + "info": { |
| 109 | + "title": "Swagger Db2 WA Extensions", |
| 110 | + "description": "This is a Swagger Connecting WA to a Db2 using Cloud Function", |
| 111 | + "version": "1.0.0" |
| 112 | + }, |
| 113 | + "servers": [ |
| 114 | + { |
| 115 | + "url": "https://xxxxxxxx", |
| 116 | + "description": "Dallas, USA" |
| 117 | + } |
| 118 | + ], |
| 119 | + "paths": { |
| 120 | + "/xxxxx/xxxxx/xxxxx.json": { |
| 121 | + "post": { |
| 122 | + "parameters": [], |
| 123 | + "summary": "Send user info", |
| 124 | + "description": "Send info from user to db2 database", |
| 125 | + "operationId": "sendUserInfo", |
| 126 | + "requestBody": { |
| 127 | + "description": "Payload to send user info to db2 database.", |
| 128 | + "content": { |
| 129 | + "application/json": { |
| 130 | + "schema": { |
| 131 | + "type": "object", |
| 132 | + "properties": { |
| 133 | + "name": { |
| 134 | + "type": "string", |
| 135 | + "description": "user name" |
| 136 | + }, |
| 137 | + "email": { |
| 138 | + "type": "string", |
| 139 | + "description": "user email" |
| 140 | + }, |
| 141 | + "address": { |
| 142 | + "type": "string", |
| 143 | + "description": "user address" |
| 144 | + } |
| 145 | + } |
| 146 | + } |
| 147 | + } |
| 148 | + }, |
| 149 | + "required": true |
| 150 | + }, |
| 151 | + "responses": { |
| 152 | + "200": { |
| 153 | + "description": "Successful operation.", |
| 154 | + "content": { |
| 155 | + "application/json": { |
| 156 | + "schema": { |
| 157 | + "type": "object", |
| 158 | + "properties": { |
| 159 | + "user_info": { |
| 160 | + "type": "string" |
| 161 | + } |
| 162 | + } |
| 163 | + } |
| 164 | + } |
| 165 | + } |
| 166 | + }, |
| 167 | + "405": { |
| 168 | + "description": "Invalid input." |
| 169 | + } |
| 170 | + } |
| 171 | + } |
| 172 | + } |
| 173 | + } |
| 174 | +} |
| 175 | +``` |
| 176 | + |
| 177 | +!!! note "Request Body Properties" |
| 178 | + |
| 179 | + For the requestBody section (starting on line 21), you can see that there are 3 “properties” defined here |
| 180 | + |
| 181 | + - name: a string (line 28) |
| 182 | + - email: a string (line 32) |
| 183 | + - address: a string (line 36) |
| 184 | + |
| 185 | + They are required parameters that the user will input when they interact with watsonx Assistant. |
| 186 | + |
| 187 | +### Integrating Custom Extenstion in watsonx Assistant |
| 188 | + |
| 189 | +Go to your watsonx Assistant instance. Navigate to the **Integrations** tab from the menu on the left-hand side of the page. |
| 190 | + |
| 191 | + |
| 192 | + |
| 193 | +From the integrations page, scroll down to the **Extensions** section and click on the **Build custom extension** button. |
| 194 | + |
| 195 | + |
| 196 | + |
| 197 | +On the **Get started** screen, click the **Next** button in the top right corner of the screen to get to the **Basic information** section. Name your extension, give it a description, and click **Next**. |
| 198 | + |
| 199 | + |
| 200 | + |
| 201 | +On the next page, upload the OpenAPI file you created from the previous steps. |
| 202 | + |
| 203 | + |
| 204 | + |
| 205 | +Click **Finish** in the top right corner. |
| 206 | + |
| 207 | +You will see that the extension you just built is now under the **Extensions** section. Click on **Add** on the bottom right corner of the tile. On the next pop-up screen, click the **Add** button. |
| 208 | + |
| 209 | + |
| 210 | + |
| 211 | +On the Get started screen, click on **Next** in the top right corner to get to the next screen. Make sure your server is correct, and click on **Next**. |
| 212 | + |
| 213 | + |
| 214 | + |
| 215 | +On the “Review operations” screen, click on “Finish” to have the extension added to your Assistant. |
| 216 | + |
| 217 | + |
| 218 | + |
| 219 | +### Create Action in watsonx Assistant |
| 220 | + |
| 221 | +Now that we've created the extension, let's go and create the action that will use this extension to send the user info variables from watsonx Assistant to the database. |
| 222 | + |
| 223 | + |
| 224 | + |
| 225 | +First, we'll want to create the variables that we need to send over to store in the database: name, email, and address. |
| 226 | + |
| 227 | +To create variables, we'll need to go to **Created by you** under **Variables**. |
| 228 | + |
| 229 | + |
| 230 | + |
| 231 | +Click on **New variable** in the top right corner to create our first variable. |
| 232 | + |
| 233 | +Fill in the **Name** and select the **Type** as well for our _name_ variable that is going to be accepted as _Free text_. Click **Save** to create the variable. |
| 234 | + |
| 235 | + |
| 236 | + |
| 237 | +Now, repeat this step 2 times but for the other variables that we need: email and address. |
| 238 | + |
| 239 | + |
| 240 | + |
| 241 | + |
| 242 | + |
| 243 | +Now, navigate back to the action page. |
| 244 | + |
| 245 | + |
| 246 | + |
| 247 | +Click on **New action** in the top right corner to create our action. Select **Start from scratch** for how we want to build our action. |
| 248 | + |
| 249 | +In the following pop up box, regarding how to start the interaction, we can enter "user info" as the input the user would type to begin this interaction. This prompt to start the interaction can be changed later on as well. Click **Save**. |
| 250 | + |
| 251 | + |
| 252 | + |
| 253 | +Click on Step 1, in this step we would ask the user what the user's name is under **Assistant says**. Names should be accepted as free text (string), so click on **Define customer response** and select **Free text** from the list. |
| 254 | + |
| 255 | + |
| 256 | + |
| 257 | +Use the blue **New step** button to create the second step. Before the Assistant does anything in the second step, we should make sure it collects the user’s response for what the user's name is from the previous step. Click on **Set variable values** in the top right corner, **Set new value**, and click on **Session variables**. |
| 258 | + |
| 259 | + |
| 260 | + |
| 261 | +Under **Session variables**, choose **_name_** from the list, and in the **To** field, click on **Action variables** and select the question you asked the user in the first step. |
| 262 | + |
| 263 | + |
| 264 | + |
| 265 | +Now that we have saved the user’s name as a variable, we also want to know what their email is. Under **Assistant says**, ask them what their email is. Under **Define customer response**, select **Free text** (similar to what you did in step 1). |
| 266 | + |
| 267 | + |
| 268 | + |
| 269 | +Use the blue **New step** button to create the third step. Similar to the second step, we should make sure it collects the user’s response for what the user's email is from the previous step. Click on **Set variable values** in the top right corner, **Set new value**, and click on **Session variables**. Set **_name_** to the **Action variable** from the question you asked the user in the second step. |
| 270 | + |
| 271 | + |
| 272 | + |
| 273 | +Repeat the same steps for the third and final variable: address. |
| 274 | + |
| 275 | + |
| 276 | + |
| 277 | + |
| 278 | + |
| 279 | +Now, we'll create a new step to send our set variables to be stored into the database. So, create a new step as you did before. Under **And then**, select "Continue to next step" and change it to "Use an extension". |
| 280 | + |
| 281 | + |
| 282 | + |
| 283 | +In the following pop up, select the following options. Under **Extension**, select the custom extension we created "user-info-extension". Under **Operation**, select the one operation we listed in the OpenAPI file "Send user info". And then, under **Optional parameters**, set each parameter to the variables we just in the previous steps (name, email, and address). Click **Apply**. |
| 284 | + |
| 285 | + |
| 286 | + |
| 287 | +Great! Now, we have the extension set up to send the acquired data to our database. |
| 288 | + |
| 289 | +If you want, you can test the extension by clicking the **Preview** button in the bottom right corner. Make sure to use the phrase we set to prompt this action to begin (we set the prompt as "user info" but you can change it to whatever you want). |
0 commit comments