Connecting Rasa to a database to store responses - python-3.x

I'm trying to connect my rasa open source chatbot to a local database and store response from the user. But I couldn't succeed in the process of integrating database to my chatbot. I tried using google but nothing seems to be working. I hope I'll get a solution from community members. Attaching the data for your reference.
nlu.yml
nlu:
- intent: painting_request
examples: |
- im interested in buying a painting
- i'm interested in buying a painting
- I'm interested in buying a painting
- interested in buying canvas
- id like to request a painting
- id like to buy a painting
- im looking for a painting that have a beautuful background
- i would like to get a sketch of my photograph
- i would like to get a sketch of my photo
- intent: art_type_entry
examples: |
- im looking for a [graphite](art_type) painting
- i'm looking for a [graphite](art_type) sketch
- i want to buy a [graphite](art_type) painting
- i want to buy a [graphite](art_type) sketch
- can i able to get a [graphite](art_type) art
- i want my picture to be drawn in [graphite](art_type)
- im looking for a [charcoal](art_type) painting
- i'm looking for a [charcoal](art_type) sketch
- i want to buy a [charcoal](art_type) painting
- i want to buy a [charcoal](art_type) sketch
- can i able to get a [charcoal](art_type) art
- i want my picture to be drawn in [charcoal](art_type)
- im looking for a [coloured pencil art](art_type) painting
- i'm looking for a [coloured pencil art](art_type) sketch
- i want to buy a [coloured pencil art](art_type) painting
- i want to buy a [coloured pencil art](art_type) sketch
- can i able to get a [coloured pencil art](art_type) art
- i want my picture to be drawn in [coloured pencil art](art_type)
- i want my picture to be drawn in [oil painting](art_type)
- im looking for a [oil painting](art_type) painting
- i'm looking for a [oil painting](art_type) sketch
- i want to buy a [oil painting](art_type) painting
- i want to buy a [oil painting](art_type) sketch
- can i able to get a [oil painting](art_type) art
- i want my picture to be drawn in [oil painting](art_type)
- intent: size_entry
examples: |
- size should be of [a4](size)
- size should be of [a3](size)
- size should be of [a2](size)
- size should be of [a1](size)
- painting should be of [a4](size)
- painting should be of [a3](size)
- painting should be of [a2](size)
- painting should be of [a1](size)
- intent: frame_entry
examples: |
- my frame should be of [standard](frame)
- my frame should be of [wooden](frame)
- my frame should be of [designer](frame)
- my canvas should be fitted with a [standard](frame)
- my canvas should be fitted with a [wooden](frame)
- my canvas should be fitted with a [designer](frame)
- frame should be of [standard](frame)
- frame should be of [Wooden](frame)
- frame should be of [designer](frame)
- intent: finishing_entry
examples: |
- the outer finishing should be done with [maple](finishing)
- the outer finishing should be done with [walnut](finishing)
- the outer finishing should be done with [black](finishing)
- the outer finishing should be done with [white](finishing)
- the outer finishing should be done with [glass](finishing)
- outer finishing should be done with [brass](finishing)
- outer finishing should be done with [maple](finishing)
- outer finishing should be done with [walnut](finishing)
- outer finishing should be done with [black](finishing)
- outer finishing should be done with [white](finishing)
- outer finishing should be done with [glass](finishing)
- outer finishing should be done with [brass](finishing)
- intent: orientation_entry
examples: |
- orientation of canvas should be in [landscape](orientation)
- orientation of canvas should be in [potrait](orientation)
- orientation of canvas should be in [designer choice](orientation)
rules.yml
rules:
- rule: activate painting form
steps:
- intent: painting_request
- action: painting_form
- active_loop: painting_form
- rule: submit form
condition:
- active_loop: painting_form
steps:
- action: painting_form
- active_loop: null
- action: utter_submit
- action: utter_slots_values
stories.yml
stories:
- story: confirmation
steps:
- intent: affirm
- action: utter_affirm
- story: stop form + continue
steps:
- intent: painting_request
- action: painting_form
- active_loop: painting_form
- intent: out_of_scope
- action: utter_ask_continue
- intent: affirm
- action: painting_form
- active_loop: null
- action: utter_submit
- action: utter_slots_values
- story: stop form + stop
steps:
- intent: painting_request
- action: painting_form
- active_loop: painting_form
- intent: out_of_scope
- action: utter_ask_continue
- intent: deny
- action: action_deactivate_loop
- active_loop: null
domain.yml
intents:
- greet
- goodbye
- affirm
- reject
- mood_great
- mood_unhappy
- bot_challenge
- askname
- help
- out_of_scope
- art_type_entry
- size_entry
- frame_entry
- finishing_entry
- orientation_entry
- painting_request:
use_entities: []
entities:
- art_type
- size
- frame
- finishing
- orientation
actions:
- validate_painting_form # From actions.py page
slots:
model:
type: text
influence_conversation: false
auto_fill: false
frame_size:
type: text
influence_conversation: false
auto_fill: false
frame_type:
type: text
influence_conversation: false
auto_fill: false
frame_orientation:
type: text
influence_conversation: false
auto_fill: false
frame_finishing:
type: text
influence_conversation: false
auto_fill: false
requested_slot:
type: text
influence_conversation: false
forms:
painting_form:
required_slots:
model:
- type: from_entity
entity: art_type
frame_size:
- type: from_entity
entity: size
frame_type:
- type: from_entity
entity: frame
frame_orientation:
- type: from_entity
entity: orientation
frame_finishing:
- type: from_entity
entity: finishing
responses:
utter_greet:
- text: "Hey! Welcome to My Website, how can I help you? "
- text: "Hi Welcome to My Website, how can I help you?"
utter_reject:
- text: "Sorry to hear it,How can I help you?"
- text: "Did that help you?"
utter_default:
- text: "I am not sure what you're aiming for."
- text: "I am sorry but I am not able to get you."
- text: "My appologies but I am not able to get you."
utter_happy:
- text: "Great, carry on!"
utter_cheer_up:
- text: "Sorry to hear that."
utter_affirm:
- text: "Nice to hear it"
utter_goodbye:
- text: "Bye"
utter_name:
- text: "I am a bot, powered by Rasa."
utter_bot_help:
- text: "I'm here to help you in customising your painting."
- text: "I'm powered by A.I here to helps you in guide to buy a beautiful painting with your desired customisation."
- text: "I'm here to gather information of how you want your painting to be."
utter_ask_continue:
- text: "Do you want to continue?"
utter_wrong_art_type:
- text: "Sorry we are unable to proceed with your art type, please try again"
utter_wrong_size_type:
- text: "Sorry we are unable to proceed with your size type, please try again"
utter_wrong_frame_type:
- text: "Sorry we are unable to proceed with your frame type, please try again"
utter_wrong_finishing_type:
- text: "Sorry we are unable to proceed with your finishing type, please try again"
utter_wrong_orientation_type:
- text: "Sorry we are unable to proceed with your orientation type, please try again"
utter_ask_model:
- text: "What is your desired art model"
utter_ask_frame_size:
- text: "Please enter your required size"
utter_ask_frame_type:
- text: "Please enter your desired frame type"
utter_ask_frame_finishing:
- text: "Please enter your deisired finishing"
utter_ask_frame_orientation:
- text: "Please enter orientation"
utter_submit:
- text: "Thanks for the information provided."
utter_slots_values:
- text: "I am going to run a search using the following parameters:\n
- art_type: {model}\n
- size: {frame_size}\n
- frame: {frame_type}\n
- finishing: {frame_finishing}\n
- orientation: {frame_orientation}"
session_config:
session_expiration_time: 60
carry_over_slots_to_new_session: true
actions.py
from database_connector import DataUpdate
from typing import Any, Text, Dict, List, Union
from rasa_sdk import Tracker
from rasa_sdk.executor import CollectingDispatcher
from rasa_sdk.forms import FormValidationAction
class PaintingFormValidation(FormValidationAction):
"""Example of a form validation action."""
def name(self) -> Text:
return "validate_painting_form"
def slot_mappings(self) -> Dict[Text, Union[Dict, List[Dict]]]:
return{
"model": [self.from_entity(entity='art_type', intent='art_type_entry')],
"frame_size": [self.from_entity(entity='size', intent='size_entry')],
"frame_type": [self.from_entity(entity='frame', intent='frame_entry')],
"frame_finishing": [self.from_entity(entity='finishing', intent='finishing_entry')],
"frame_orientation": [self.from_entity(entity='orientation', intent='orientation_entry')]
}
#staticmethod
def art_type_db() -> List[Text]:
"""Database of supported cuisines."""
return [
"graphite",
"charcoal",
"sketching",
"oilPainting",
"colored pencil"
]
#staticmethod
def size_db() -> List[Text]:
"""Database of supported sizes"""
return [
"a1",
"a2",
"a3",
"a4"
]
#staticmethod
def frame_db() -> List[Text]:
"""Database of supported frame types"""
return [
"no frame",
"standard",
"designer"
]
#staticmethod
def finishing_db() -> List[Text]:
"""Database of supported finishing"""
return [
"maple",
"wood",
"metal",
"glass",
"walnut"
]
#staticmethod
def orientation_db() -> List[Text]:
"""Database of supported orientations."""
return [
"landscape",
"potrait",
"designer choice"
]
#staticmethod
def is_int(string: Text) -> bool:
"""Check if a string is an integer."""
try:
int(string)
return True
except ValueError:
return False
def validate_model(
self,
value: Text,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any],
) -> Dict[Text, Any]:
"""Validate art type value."""
if value.lower() in self.art_type_db():
# validation succeeded, set the value of the "art_type" slot to value
return {"model": value}
else:
dispatcher.utter_message(response="utter_wrong_art_type")
# validation failed, set this slot to None, meaning the
# user will be asked for the slot again
return {"model": None}
def validate_frame_size(
self,
value: Text,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any],
) -> Dict[Text, Any]:
"""Validate size value."""
if value.lower() in self.size_db():
# validation succeeded, set the value of the "size" slot to value
return {"frame_size": value}
else:
dispatcher.utter_message(response="utter_wrong_size_type")
# validation failed, set this slot to None, meaning the
# user will be asked for the slot again
return {"frame_size": None}
def validate_frame_type(
self,
value: Text,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any],
) -> Dict[Text, Any]:
"""Validate frame type value."""
if value.lower() in self.frame_db():
# validation succeeded, set the value of the "frame" slot to value
return {"frame_type": value}
else:
dispatcher.utter_message(response="utter_wrong_frame_type")
# validation failed, set this slot to None, meaning the
# user will be asked for the slot again
return {"frame_type": None}
def validate_frame_finishing(
self,
value: Text,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any],
) -> Dict[Text, Any]:
"""Validate finishing value."""
if value.lower() in self.finishing_db():
# validation succeeded, set the value of the "finishing" slot to value
return {"frame_finishing": value}
else:
dispatcher.utter_message(response="utter_wrong_finishing_type")
# validation failed, set this slot to None, meaning the
# user will be asked for the slot again
return {"frame_finishing": None}
def validate_frame_orientation(
self,
value: Text,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any],
) -> Dict[Text, Any]:
"""Validate orientation value."""
if value.lower() in self.orientation_db():
# validation succeeded, set the value of the "orientation" slot to value
return {"frame_orientation": value}
else:
dispatcher.utter_message(response="utter_wrong_orientation_type")
# validation failed, set this slot to None, meaning the
# user will be asked for the slot again
return {"frame_orientation": None}
def submit(
self,
dispatcher:CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any]
) -> List[Dict]:
dispatcher.utter_message(template="utter_submit")
DataUpdate(tracker.get_slot("model"), tracker.get_slot("frame_size"), tracker.get_slot("frame_type"), tracker.get_slot("frame_finishing"), tracker.get_slot("frame_orientation"))
dispatcher.utter_message("Your response has been loaded.")
return []
database_connector.py
import psycopg2
def DataUpdate(art_type_entry, size_entry, frame_entry, finishing_entry, orientation_entry):
'''
Pushes Descriptive Analytics Data to the Database
'''
db = psycopg2.connect(
host="localhost",
database="Rasa_Chatbot",
user="postgres",
password="postgres"
)
mycursor = db.connect()
postgres_insert_query = """INSERT INTO rasainfo(model,size,type,orientation,finishing) VALUES (%s,%s,%s,%s,%s);""".format(art_type_entry,size_entry, frame_entry, finishing_entry, orientation_entry)
mycursor.execute(postgres_insert_query)
db.commit()
print("Record inserted successfully into table")

You need to define this in your endpoints.yml
tracker_store:
type: SQL
dialect: "postgresql" # the dialect used to interact with the db
url: "postgres"
db: "rasa" # path to your db
username: # username used for authentication
password: # password used for authentication
query: # optional dictionary to be added as a query string to the connection URL
driver: my-driver

Related

RASA 2.8 - Final custom action in rules are not run

I'm trying to setup a bot that takes three inputs, two from buttons, and one from text. Currently, I'm able to pass in all of the required input. However, when it comes time for the final action, the bot does not seem to know what to do, and returns either a greeting or a message that it does not understand me. Is there anything wrong with my rules or domain files?
rule.yml
version: "2.0"
rules:
- rule: Activate conv_get_job_status
steps:
- intent: get_job_query
- action: action_populate_user_bot_info
- action: job_type_selection #this creates a list of buttons for job type selection
- action: job_type_input #job type form, to set job_type slot
- active_loop: job_type_input
- rule: Submit conv_get_job_status
condition:
- active_loop: job_type_input
- active_loop: job_name_and_number_input
steps:
- action: job_type_input
- active_loop: null
- slot_was_set:
- requested_slot: null
- action: job_name_selection #this creates a list of buttons for job name selection
- action: job_name_and_number_input #job name and number form, to set job_name and job number slots
- active_loop: job_name_and_number_input
- action: job_name_and_number_input
- active_loop: null
- slot_was_set:
- requested_slot: null
- action: action_return_job_status #various utterances, currently not called.
testjob_domain.yml
version: '2.0'
entities:
- job_type
- job_name
- job_number
intents:
- get_job_query
actions:
- action_reset_job_type_input
- job_number_query
- utter_ask_job_number
- utter_ask_job_name
- utter_ask_job_type
- action_return_job_status
- job_name_selection
- get_job_status
- action_reset_get_job_status
- job_type_selection
- action_reset_job_name_and_number_input
responses:
utter_ask_job_type:
- text: Select job type
utter_ask_job_name:
- text: Select job name
utter_ask_job_number:
- text: Enter job number
slots:
execute_action:
type: text
job_type:
type: text
job_name:
type: text
job_number:
type: text
forms:
job_type_input:
job_type:
- type: from_text
intent_name: None
job_name_and_number_input:
job_name:
- type: from_text
intent_name: None
job_number:
- type: from_text
intent_name: None
The code for action_return_job_status:
from .action_utils import *
class ActionReturnJobStatus(Action):
def name(self):
return "action_return_job_status"
def run(self, dispatcher, tracker, domain):
logger.info("Action - action_return_job_status")
logger.info("execute_action_slot: "+str(tracker.slots['execute_action']))
record_bot_event(tracker, dispatcher, 'new_session', auth_critical=authorization_critical)
# set auth_critical=True to skip action code execution
if not verifyBAMToken(tracker, dispatcher, auth_critical=authorization_critical):
return
logger.info("RUNNING GET ACTION")#I would expect to see either this in the logs or the utterances. Neither happens
dispatcher.utter_message("RUNNING GET ACTION")
return [SlotSet('latest_faq_question', None), SlotSet('latest_application_name', None)]

dump ruamel yaml - preserving the original structure

I have this yaml file (file_in.yaml),
components: &base
type1: 3 # sample comment
type2: 0x353
type3: 1.2.3.4
type4: "bla"
schemas:
description: 'ex1' # this is comment
description: 'ex2'
test2:
<<: *base
type4: 4555 # under the sea :)
yellow: &yellow
bla: 1
collor: &yellow
bla: 2
paint:
color: *yellow
slot_si_value_t: &bla1
desc: hav slot 2
slot_number: 2 #SI_SLOT_2
inst_max: 4
slot_si_value_t: &bla2
desc: hav slot 4
slot_number: 4 #SI_SLOT_4
inst_max: 4
slot:
- slot_si_value: *bla1
- slot_si_value: *bla2
I load it with this code snippet, and dump it into another file.
import ruamel.yaml
ryaml = ruamel.yaml.YAML()
ryaml.allow_duplicate_keys = True
ryaml.preserve_quotes = True
with open("file_in.yaml") as si_file:
si_data = ryaml.load(si_file)
with open("file_out.yaml", "w") as fp:
ryaml.dump(si_data, fp)
the file_out.yaml looks like this,
components: &base
type1: 3 # sample comment
type2: 0x353
type3: 1.2.3.4
type4: "bla"
schemas:
description: 'ex1' # this is comment
test2:
<<: *base
type4: 4555 # under the sea :)
yellow:
bla: 1
collor: &yellow
bla: 2
paint:
color: *yellow
slot_si_value_t: &bla1
desc: hav slot 2
slot_number: 2 #SI_SLOT_2
inst_max: 4
slot:
- slot_si_value: *bla1
- slot_si_value:
desc: hav slot 4
slot_number: 4 #SI_SLOT_4
inst_max: 4
I can see that the comments, quotes, hex values and the order are preserved, however the structure of the yaml is changed. Is there any ways to instruct ruamel to dump the exact format?
here is a side-by-side comparison,
You can preserve all anchors by changing the .yaml_set_anchor method of the CommentedBase. For
historical reasons this is currently only done for scalar values that are anchored (i.e. it is inconsistent).
Having duplicate keys in your YAML mappings however makes the document invalid, because keys have to be unique
according to the YAML specification. In order
to allow loading of these faulty documents ruamel.yaml allows you to load such broken
documents by setting .allow_duplicate_keys, but it doesn't support writing such incorrect documents
and disregards further occurrences of the same key in a mapping (during loading, so you cannot access the values for those keys, unless the are anchored and aliased somewhere else).
That is why you "lose" the description: 'ext2' under key schemas, including the following
empty line (which is part of that entries "comment")
The second occurrence of slot_si_value_t in the root mapping causes more problems. Because
it is not preserved, the &bla2 anchored mapping exists only once in the loaded
data and gets dumped (with an anchor because the .yaml_set_anchor change), within
the sequence that is the value of slot.
import sys
import warnings
from pathlib import Path
import ruamel.yaml
def yaml_set_anchor(self, value, always_dump=True):
self.anchor.value = value
self.anchor.always_dump = always_dump
ruamel.yaml.comments.CommentedBase.yaml_set_anchor = yaml_set_anchor
in_file = Path('file_in.yaml')
yaml = ruamel.yaml.YAML()
yaml.allow_duplicate_keys = True
yaml.preserve_quotes = True
with warnings.catch_warnings():
warnings.simplefilter("ignore")
data = yaml.load(in_file)
yaml.dump(data, sys.stdout)
which gives:
components: &base
type1: 3 # sample comment
type2: 0x353
type3: 1.2.3.4
type4: "bla"
schemas:
description: 'ex1' # this is comment
test2:
<<: *base
type4: 4555 # under the sea :)
yellow: &yellow
bla: 1
collor: &yellow
bla: 2
paint:
color: *yellow
slot_si_value_t: &bla1
desc: hav slot 2
slot_number: 2 #SI_SLOT_2
inst_max: 4
slot:
- slot_si_value: *bla1
- slot_si_value: &bla2
desc: hav slot 4
slot_number: 4 #SI_SLOT_4
inst_max: 4
You should update your input file to dispose, or change, the duplicate keys. Even
then this will not exactly round-trip in ruamel.yaml since you have inconsistent
indentation ( e.g. the root level mapping indents two spaces for components and
four spaces for slot_si_value_t ), and that is being normalized.

How to modify current ScreenManager to another

Good afternoon.
I have a code structure with two ScreenManager:
id: sm ==> besides being my root it has only two screens
LoginScreen:
name: 'screen_login'
MainScreen:
name: 'main'
When the login is performed it directs me to the main screen:
On the screen named 'main' it has:
1 - MDToolbar
1 - MDNavigationLayout and it has a ScreenManager of
id: screen_manager with the following screens:
ScreenRecycleView
LoginScreen
ScreenSingUp
ScreenItem
1 - MDNavigationDrawer and it has a ContentNavigationDrawer with a creen_manager variable that inherits from the one described above.
There it is working beautifully!
I call any of the screens above and everything runs.
The problem is that I have a screen called
<ScreenRecycleView>:
name: 'recycle_view'
and this one has a MyImageCard class that has a button:
MDFlatButton:
text: "New Screen Here"
increment_width: "164dp"
On it I click and I can't call the screen that I pointed out in the example.
on_release:
app.root.screen_manager.current = 'screen_item'
I've tried everything I know, I'm for your help.
Below is my code reduced to the max to help them help me:
My code here.
I know my problem is screen manager but I can't solve it!
With your help I was able to discover:
app.root.get_screen('main').ids.screen_manager.current = 'screen_item'

extract substrings using python regex

I would like to use a regular expression that matches any text between two strings:
sample_string= "Message ID: SM9MatRNTnMAYaylR0QgOH///qUUveBCbw==
2021-07-10T20:48:23.997Z john s (X Y Bank) -
john.s#xy.com:
[EVENT] 347376954900491 (john.s#xy.com) created room
(roomName='CSTest' roomDescription='CS Test Chat Room' COPY_DISABLED=false
READ_ONLY=false DISCOVERABLE=false MEMBER_ADD_USER_ENABLED=false
roomType=PRIVATE conversationScope=internal owningCompany=X Y
Bank)
Message ID: nsabNaqeXfuEj9mBEhvS0n///qUUveAhbw==
2021-07-10T20:48:23.997Z john s (X Y Bank) -
john.s#xy.comsays
[EVENT] 347376954900491 (john.s#xy.com) invited 347376954900486
(kerren.n#xy.com) to room (CSTest|john s|16091907435583)
Message ID: Nu/EYTkTQ5qdbqzZ0Rig8n///qUUvQ42dA==
2021-07-10T20:48:23.997Z john s (X Y Bank) -
john.s#xy.comsays
Catchyou later
Message ID: dy2yaByqhm+n88Gd3VQOhH///qUUrz8odA==
2021-07-10T20:48:23.997Z kerren n (X Y Bank) -
nancy.n#xy.comsays
KeywordContent_ Cricket is a bat-and-ball game played between two teams of
eleven players on a field at the centre of which is a 20-metre (22-yard) pitch
with a wicket at each end, each comprising two bails balanced on three stumps.
The batting side scores runs by striking the ball bowled at the wicket with
the bat, while the bowling and fielding side tries to prevent this and dismiss
each player (so they are "out").
* * *
Generated by Content Export Service | Stream Type: SymphonyPost |
Stream ID: ZZo5pRRPFC18uzlonFjya3///qUUveBHdA== | Room Type: Private |
Conversation Scope: internal | Owning Company: X Y Bank | File
Generated Date: 2021-07-10T20:48:23.997Z | Content Start Date:
2021-07-10T20:48:23.997Z | Content Stop Date: 2021-07-10T20:48:23.997Z
* * *
*** (780787) Disclaimer:
(incorporated in paris with Ref. No. ZC18, is authorised by Prudential Regulation
Authority (PRA) and regulated by Financial Conduct Authority and PRA. oyp and
its affiliates (We) monitor this confidential message meant for your
information only. We make no recommendation or offer. You should get
independent advice. We accept no liability for loss caused hereby. See market
commentary disclaimers (
http://wholesalebanking.com/en/utility/Pages/d-mkt.aspx ),
Dodd-Frank and EMIR disclosures (
http://wholesalebanking.com/en/capabilities/financialmarkets/Pages/default.aspx
) "
In this example, I would like to extract everything after emailID and keyword Messaage ID:
so expected output would be:
extracted_list =[':
[EVENT] 347376954900491 (john.s#xy.com) created room
(roomName='CSTest' roomDescription='CS Test Chat Room' COPY_DISABLED=false
READ_ONLY=false DISCOVERABLE=false MEMBER_ADD_USER_ENABLED=false
roomType=PRIVATE conversationScope=internal owningCompany=X Y
Bank)','says
[EVENT] 347376954900491 (john.s#xy.com) invited 347376954900486
(kerren.n#xy.com) to room (CSTest|john s|16091907435583)','says Catchyou later','says
KeywordContent_ Cricket is a bat-and-ball game played between two teams of
eleven players on a field at the centre of which is a 20-metre (22-yard) pitch
with a wicket at each end, each comprising two bails balanced on three stumps.
The batting side scores runs by striking the ball bowled at the wicket with
the bat, while the bowling and fielding side tries to prevent this and dismiss
each player (so they are "out").']
Note: everything after *** at last is not the part of text
What I tried so far is:
text = re.findall(r'\S+#\S+\s+(.*)Message ID', sample_string)
print (text)
##output: []
You can use
(?s)\S+#\S+?((?:says?|:)?\s.*?)\s+(?:Message ID|\* +\* +\*)
See the regex demo.
Details:
(?s) - same as re.DOTALL, inline modifier to make . match across line breaks
\S+ - one or more non-whitespace chars (can be replaced with [^\s#]+)
# - a # char
\S+? - one or more non-whitespace chars as few as possible
((?:says?|:)?\s.*?) - Group 1: an optional says/say/: and then a whitespace and then any zero or more chars as few as possible
\s+ - one or more whitespaces
(?:Message ID|\* +\* +\*) - either Message ID or * * * like substring.

Rasa NLU: How to use multiple categorical slots with same values?

I just started working with Rasa NLU and I have some problem understanding the usage of categorical slots with same values. I have 3 different types of risk, each a categorical slot with values: low, medium and high.
How can the bot differentiate between the three risks and understand which slot to be filled up, given the intent is same for each.
Or do I need to use different intents for each?
Right now what I see is (I removed unrelated logs):
How tired are you?
1: low (low)
2: medium (medium)
3: high (high)
medium
DEBUG:rasa_core.processor:Received user message 'medium' with intent '{'name': 'inform', 'confidence': 0.88372623999657118}' and entities '[{'start': 0, 'end': 6, 'value': 'medium', 'entity': 'fatigue', 'extractor': 'ner_crf'}]'
DEBUG:rasa_core.processor:Current slot values:
fatigue: medium
injury: None
stress: None
How stressed are you?
1: low (low)
2: medium (medium)
3: high (high)
low
DEBUG:rasa_core.processor:Received user message 'low' with intent '{'name': 'inform', 'confidence': 0.88762049990079372}' and entities '[{'start': 0, 'end': 3, 'value': 'low', 'entity': 'fatigue', 'extractor': 'ner_crf'}]'
DEBUG:rasa_core.processor:Current slot values:
fatigue: low
injury: None
stress: None
All the user replies have the intent inform.
An example story is:
* _greet[]
- utter_ask_fatigue
* _inform[fatigue=low]
- utter_ask_injury
* _inform[injury=medium]
- utter_ask_stress
* _inform[stress=low]
- utter_on_it
- action_reply
you can do it with one entity and four slots
the entity may be defined as type "info", with text values (i.e. low, medium, high).
The four slots: the first one is "info", which will auto filled by recognized entity "info" defined previously. The other three would be "fatigue", "stress" and "injury", which can be filled by bot actions such as action_fill_fatigue, action_fill_stress and action_fill_injury.
an example story will make it clear:
* _greet[]
- utter_ask_fatigue
* _inform[info=low]
- action_fill_fatigue
- utter_ask_injury
* _inform[info=medium]
- action_fill_injury
- utter_ask_stress
* _inform[info=low]
- action_fill_stress
- utter_on_it
- action_reply

Resources