1

I'm working on a chatbot project which fetches "delivery status" information from a database. I've defined a function (lets call it db_info) which will connect to my DB and then get the results.

I have a .json file which has different intents like "Greeting", "Status Check", "Closing" etc. The way the application works is - whenever the user types in something, the text is classified into an intent. For ex: when the user types "Hi" the application recognizes it is from the intent "Greeting" and then gives out one of the responses I hard coded in the .json file.

However, for the "Status Check" intent I don't want the application to give out some hard coded response from .json file. Instead, I'd like it to call the db_info function when the intent "Status Check" is identified.

I'm aware that a function map (dictionary) can be created in .py file and then its value can be called in the json file. But I'm not sure how this is done exactly.

def db_info(): --> lives in .py file
   # connect to postgres and get some information

if intent == 'greetings':
   # pick random statement from "responses" of tag "greeting" from json file

if intent == 'status_check':
   # go to "responses" under tag "status_check" and run the func mentioned there
   def db_info():
       # instead of picking up a random statement from "response" this func needs to be called

My json file:

{"tag": "greetings",
 "pattern": ["Hi", "How are you", "Hey", "Hello", "Good Day"],
 "responses": ["Hello!", "Hey there", "Hi, how can I help you today?"]
},
{"tag": "status_check",
 "pattern": ["Where's my shipment", "Track my shipment"],
 "responses": ["GetDBInfo function"]
}
Tomerikoo
  • 15,737
  • 15
  • 35
  • 52
pypsy
  • 23
  • 4
  • 2
    Your question is very broad and unclear. It will help to have a [mre] to better understand the context of your problem. I mean, why not do `if intent is "Status Check": db_info(...)` (pseudo)? – Tomerikoo Nov 25 '21 at 15:10
  • I have made some edits. Please note that I added an image url to show my json file. Kindly check and let me know if this made my question clear. – pypsy Nov 25 '21 at 15:37
  • Welcome to Stack Overflow! Please avoid posting images (or worse, links to images) of code or errors. Anything text-based (code and errors) should be posted as text directly in the question itself and formatted properly as a [mre]. You can get more [formatting help here](https://stackoverflow.com/help/formatting). You can also read about [why you shouldn't post images/links of code](//meta.stackoverflow.com/q/285551). – Tomerikoo Nov 25 '21 at 15:40
  • Also, it is not clear what is your question. Which one of the comments are you having troubles with to implement? – Tomerikoo Nov 25 '21 at 15:42
  • Does this answer your question? [Calling a function of a module by using its name (a string)](https://stackoverflow.com/q/3061/6045800) For example: `if intent == 'status_check': globals()[intents["status_check"]["responses"][0]]()` – Tomerikoo Nov 25 '21 at 15:43
  • I'm looking to configure my json file like - when status_check is identified, my application should hit the responses section of that tag in json file, but it should instead run the db_info function and not just give out the text present in the "response". – pypsy Nov 25 '21 at 15:48
  • @Tomerikoo I'm afraid that doesn't answer my question. Is there a way to call the db_info function from json file? For example: "tag": "status_check", "pattern": "Track my shipment", "responses": [run db_info function] – pypsy Nov 25 '21 at 15:56
  • What do you mean from the json file? json is not code, it's just data. You parse that with Python code... You call the function through Python – Tomerikoo Nov 25 '21 at 15:57
  • You can modify the json to have another field `"func"` which will just be `"print"` for all intents and for status check it will be `db_info` – Tomerikoo Nov 25 '21 at 15:58
  • 1
    Please post a [mre] of the json ***as text*** so I can post an answer to see if it's what you mean – Tomerikoo Nov 25 '21 at 16:00
  • At the moment I have my JSON like this: {"tag": "status_check", "pattern": ["check my shipment", "track my shipment", "status of shipment"], "responses": [generally contains the response I want application to give back to user.. in this case db_info] } – pypsy Nov 25 '21 at 16:02
  • Please don't use comments for that. [edit] the question with an example of your json, just so I have something to work with to show you what I had in mind – Tomerikoo Nov 25 '21 at 16:04
  • Added sample json to my question. – pypsy Nov 25 '21 at 16:10
  • 1
    I'll repeat what other's have said: we need a [mcve] that will actually run. Your current code example has multiple run time errors. Instead of explaining what the code does in a comment, put some actual code. – Code-Apprentice Nov 25 '21 at 16:11
  • Universal Disk Format? – user3840170 Nov 25 '21 at 16:43
  • @user3840170, User Defined Function. – pypsy Nov 26 '21 at 08:34

1 Answers1

0

You can modify your json to match the following parsing process:

  • find the intent the pattern matches
  • get a response
  • pass it as an argument to the function of that intent

This means that you will add a "function" field to the json and call it when you parse. All intents will simply have it as "print" (or whatever other default operation you're doing) and the "Status_Check" intent will have its own special function. Then, just map the names to actual function objects that you can call.

So the json can look like this:

[{"tag": "greetings",
  "pattern": ["Hi", "How are you", "Hey", "Hello", "Good Day"],
  "function": "print",
  "responses": ["Hello!", "Hey there", "Hi, how can I help you today?"]
 },
  {"tag": "status_check",
    "pattern": ["Where's my shipment", "Track my shipment"],
    "function": "GetDBInfo",
    "responses": [""]
  }]

And to parse it:

import json
import random

def db_info(useless_arg):
    print("from func")

func_mapping = {"print": print,
                "GetDBInfo": db_info}

with open("test.json") as file:
    intents = json.load(file)

text = input("input: ")

for intent in intents:
    if text in intent["pattern"]:
        function = intent["function"]
        arg = random.choice(intent["responses"])
        func_mapping[function](arg)

An example run:

input: Where's my shipment
from func

input: Hi
Hello!
Tomerikoo
  • 15,737
  • 15
  • 35
  • 52