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