Extract data from csv in RASA

I am making a chatbot in RASA which helps High school graduates find university according to their desired location. I have all my data stored in a CSV file. So is there any way we can extract some specific data from that CSV. Example: If a user asks to show universities available in a certain location, how to extract the specific data from CSV which is the name of the university according to the location given by the user.

You can use custom actions.

In your custom action, you can connect to a database or read a CSV file like in any other Python code.

If you use slots, you can get the value of the slot in the custom action by using tracker.get_slot(slot_name).

You do your stuff with the CSV as with any other Python code and get the output, build a reply based on the output, and use the dispatcher.utter_message(reply) function to make the chatbot utter the message.

For example, in the run() method of your custom action:

# get the location slot
location = tracker.get_slot('location')

# read the CSV file
with open('universities.csv', 'r') as file:
    reader = csv.DictReader(file)
    # get a list of universities in the desired location
    output = [row for row in reader if row['Location'] == location]

if output: # there is at least one value
    # build your reply according to the output
    reply  = f"This is a list of universities in {location}:"
    reply += "\n- " + "\n- ".join([item['Name'] for item in output])
    # utter the message
    dispatcher.utter_message(reply)

else: # the list is empty
    dispatcher.utter_message(f"I could not find universities in {location}")

thank you. helped me a lot

1 Like

@ChrisRahme i did this and i am getting errors.Can you please recheck this?

class actionfindengr(Action):

def name(self) -> Text:

 return "action_findengr"

 def run(self, dispatcher: CollectingDispatcher,

         tracker: Tracker,

         domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:

    # get the location slot

     location = tracker.get_slot('location')

     # read the CSV file

     with open('data\Engineering colllege.csv', 'r') as file:

        reader = csv.DictReader(file)

        # get a list of universities in the desired location

        output = [row for row in reader if row['Location'] == location]

     if output: 

        reply  = f"This is a list of universities in {location}:"

        reply += "\n- " + "\n- ".join([item['Name'] for item in output])

        # utter the message

        dispatcher.utter_message(reply)

     else: # the list is empty

        dispatcher.utter_message(f"I could not find universities in {location}")

What’s the error?

For a start:

  • You should use \\ or / in the path instead of \.
  • Is your file named data/Engineering colllege.csv or data/Engineering college.csv?
  • Are your column names Name and Location?

rasa.shared.exceptions.RasaException: Failed to execute custom action.

raise NotImplementedError(“An action must implement its run method”) NotImplementedError: An action must implement its run method so these are the errors i am getting i changed my action to: from typing import Any, Text, Dict, List

from rasa_sdk import Action, Tracker

from rasa_sdk.executor import CollectingDispatcher

import csv

class actionfindengr(Action):

def name(self) -> Text:

 return "action_findengr"

 def run(self, dispatcher: CollectingDispatcher,

         tracker: Tracker,

         domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:

    # get the location slot

     location = tracker.get_slot('location')

     # read the CSV file

     with open('data/Engineering colllege.csv', 'r') as file:

        reader = csv.DictReader(file)

        # get a list of universities in the desired location

        output = [row for row in reader if row['Location'] == location]

     if output: 

        reply  = f"This is a list of universities in {location}:"

        reply += "\n- " + "\n- ".join([item['College'] for item in output])

        # utter the message

        dispatcher.utter_message(reply)

     else: # the list is empty

        dispatcher.utter_message(f"I could not find universities in {location}")

still the same error .and i have defined my action in domain and stories as well

Can you send me your actions.py?

actions.py (1.8 KB) @ChrisRahme here you go

1 Like

As I expected, it’s an error of indentation. Be careful with your indents in Python. actions.py (1.8 KB)

@ChrisRahme can you check on this please i am quite new to this and i am not getting solutions .

Your problem is that in your code you wrote row['location'] while the CSV key is Location with a big L.

I also added .lower() in the following line

output = [row for row in reader if row['Location'].lower() == location.lower()]

so that “trade tower” and “Trade Tower” match.

Conversation before adding .lower():

Your input ->  hi
? Hey! How can i help you??  1: find a college.. (/affirm)
ok..what field do you want to study in??
Your input ->  engineering
can you specify the location where you want to be studying??
Your input ->  trade tower
I could not find universities in trade tower
Your input ->  Trade Tower
This is a list of universities in Trade Tower:
- The British College, Kathmandu

chatbot.zip (7.2 KB)

Thankyou so much

1 Like

Hello sir @ChrisRahme I am making a chatbot in RASA which will help customer to find several details . Like if users asks What is the revenue for Company A? then chatbot should reply “for which year”.

(example) User: 2020 Chatbot: shows the revenue for Company A

and should return the value what ever is asked by the user. CSV_FILE.csv (993 Bytes) is my .csv file from which My seniors wants that chat bot should extract the information from .csv file and should retern it to use, Same as the condition defined above by AayushDangol123 . My no. of columns are more so could you please help me in building that code because I am new to this.

I shall be highly thankful to you.

code I have written in action.py file

from typing import Any, Text, Dict, List

from rasa_sdk import Action, Tracker

from rasa_sdk.executor import CollectingDispatcher

import csv

class actionfindengr(Action):

def name(self) -> Text:

    return "action_findengr"

def run(self,

        dispatcher: CollectingDispatcher,

        tracker: Tracker,

        domain: Dict[Text, Any]

    ) -> List[Dict[Text, Any]]:

    # get the location slot

    location = tracker.get_slot('location')

    # read the CSV file

    with open('C:\\Users\\om sai infotech\\OneDrive\\Desktop\\bot\\actions\\financial.csv','r',encoding = "utf-8") as file:

        reader = csv.DictReader(file)

        # get a list of universities in the desired location

        output = [row for row in reader if row['Location'] == location]

    if output:

        reply  = f"Output: {location}:"

        reply += "\n- " + "\n- ".join([item['S.No.','date','firm','Ticker','Research Development','Income Before Tax','Net Income','Selling General Administrative','Gross Profit','Ebit','Operating Income','Interest Expense','Income Tax Expense','Total Revenue','Total Operating Expenses','Cost Of Revenue','Total Other Income Expense Net','Net Income From Continuing Ops','Net Income Applicable To Common Shares'] for item in output])

        # utter the message

        dispatcher.utter_message(reply)

    else: # the list is empty

        dispatcher.utter_message(f"I could not this in {location}")

Could you please tell that whether the above code is right or wrong? if wrong then how can I do it correct?

When I run the command “rasa init” It removes the above shared code from the file. Could you please help @ChrisRahme

rasa init restarts your project, you should only do it once.

For the rest, it’s just Python, I suggest asking this question on https://stackoverflow.com/.