Spaces:
Runtime error
Runtime error
Greg Thompson
commited on
Commit
•
48c823d
1
Parent(s):
d7c0eb6
Improve code modularity and style and incorporate nlu into wormhole prototype
Browse files- app.py +5 -43
- mathtext_fastapi/conversation_manager.py +4 -0
- mathtext_fastapi/logging.py +84 -0
- mathtext_fastapi/nlu.py +74 -71
- scripts/make_request.py +145 -142
app.py
CHANGED
@@ -11,8 +11,9 @@ from mathtext.sentiment import sentiment
|
|
11 |
from mathtext.text2int import text2int
|
12 |
from pydantic import BaseModel
|
13 |
|
14 |
-
from mathtext_fastapi.
|
15 |
-
from mathtext_fastapi.conversation_manager import
|
|
|
16 |
|
17 |
app = FastAPI()
|
18 |
|
@@ -85,7 +86,7 @@ async def programmatic_message_manager(request: Request):
|
|
85 |
|
86 |
@app.post("/nlu")
|
87 |
async def evaluate_user_message_with_nlu_api(request: Request):
|
88 |
-
""" Calls
|
89 |
|
90 |
Input
|
91 |
- request.body: a json object of message data for the most recent user response
|
@@ -96,45 +97,6 @@ async def evaluate_user_message_with_nlu_api(request: Request):
|
|
96 |
{'type':'sentiment', 'data': 'negative'}
|
97 |
"""
|
98 |
data_dict = await request.json()
|
99 |
-
|
100 |
message_data = data_dict.get('message_data', '')
|
101 |
-
|
102 |
-
|
103 |
-
# Handles if a student answer is already an integer or a float (ie., 8)
|
104 |
-
if type(message_text) == int or type(message_text) == float:
|
105 |
-
nlu_response = {'type': 'integer', 'data': message_text, 'confidence': ''}
|
106 |
-
prepare_message_data_for_logging(message_data, nlu_response)
|
107 |
-
return JSONResponse(content=nlu_response)
|
108 |
-
|
109 |
-
# Removes whitespace and converts str to arr to handle multiple numbers
|
110 |
-
message_text_arr = re.split(", |,| ", message_text.strip())
|
111 |
-
|
112 |
-
# Handle if a student answer is a string of numbers (ie., "8,9, 10")
|
113 |
-
if all(ele.isdigit() for ele in message_text_arr):
|
114 |
-
nlu_response = {'type': 'integer', 'data': ','.join(message_text_arr), 'confidence': ''}
|
115 |
-
prepare_message_data_for_logging(message_data, nlu_response)
|
116 |
-
return JSONResponse(content=nlu_response)
|
117 |
-
|
118 |
-
student_response_arr = []
|
119 |
-
|
120 |
-
for student_response in message_text_arr:
|
121 |
-
# Checks the student answer and returns an integer
|
122 |
-
|
123 |
-
int_api_resp = text2int(student_response.lower())
|
124 |
-
student_response_arr.append(int_api_resp)
|
125 |
-
|
126 |
-
# '32202' is text2int's error code for non-integer student answers (ie., "I don't know")
|
127 |
-
# If any part of the list is 32202, sentiment analysis will run
|
128 |
-
if 32202 in student_response_arr:
|
129 |
-
sentiment_api_resp = sentiment(message_text)
|
130 |
-
# [{'label': 'POSITIVE', 'score': 0.991188645362854}]
|
131 |
-
sent_data_dict = {'type': 'sentiment', 'data': sentiment_api_resp[0]['label']}
|
132 |
-
nlu_response = {'type': 'sentiment', 'data': sentiment_api_resp[0]['label'], 'confidence': sentiment_api_resp[0]['score']}
|
133 |
-
else:
|
134 |
-
if len(student_response_arr) > 1:
|
135 |
-
nlu_response = {'type': 'integer', 'data': ','.join(str(num) for num in student_response_arr), 'confidence': ''}
|
136 |
-
else:
|
137 |
-
nlu_response = {'type': 'integer', 'data': student_response_arr[0], 'confidence': ''}
|
138 |
-
|
139 |
-
prepare_message_data_for_logging(message_data, nlu_response)
|
140 |
return JSONResponse(content=nlu_response)
|
|
|
11 |
from mathtext.text2int import text2int
|
12 |
from pydantic import BaseModel
|
13 |
|
14 |
+
from mathtext_fastapi.logging import prepare_message_data_for_logging
|
15 |
+
from mathtext_fastapi.conversation_manager import manage_conversational_response
|
16 |
+
from mathtext_fastapi.nlu import evaluate_message_with_nlu
|
17 |
|
18 |
app = FastAPI()
|
19 |
|
|
|
86 |
|
87 |
@app.post("/nlu")
|
88 |
async def evaluate_user_message_with_nlu_api(request: Request):
|
89 |
+
""" Calls the nlu evaluation function to run nlu functions and returns the nlu_response to Turn.io
|
90 |
|
91 |
Input
|
92 |
- request.body: a json object of message data for the most recent user response
|
|
|
97 |
{'type':'sentiment', 'data': 'negative'}
|
98 |
"""
|
99 |
data_dict = await request.json()
|
|
|
100 |
message_data = data_dict.get('message_data', '')
|
101 |
+
nlu_response = evaluate_message_with_nlu(message_data)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
return JSONResponse(content=nlu_response)
|
mathtext_fastapi/conversation_manager.py
CHANGED
@@ -3,6 +3,7 @@ import json
|
|
3 |
import requests
|
4 |
|
5 |
from dotenv import load_dotenv
|
|
|
6 |
|
7 |
load_dotenv()
|
8 |
|
@@ -161,6 +162,9 @@ def manage_conversational_response(data_json):
|
|
161 |
|
162 |
whatsapp_id = message_data['author_id']
|
163 |
user_message = message_data['message_body']
|
|
|
|
|
|
|
164 |
|
165 |
message_package = return_next_conversational_state(context_data, user_message)
|
166 |
|
|
|
3 |
import requests
|
4 |
|
5 |
from dotenv import load_dotenv
|
6 |
+
from mathtext_fastapi.nlu import evaluate_message_with_nlu
|
7 |
|
8 |
load_dotenv()
|
9 |
|
|
|
162 |
|
163 |
whatsapp_id = message_data['author_id']
|
164 |
user_message = message_data['message_body']
|
165 |
+
|
166 |
+
# TODO: Need to incorporate nlu_response into wormhole by checking answers against database (spreadsheet?)
|
167 |
+
nlu_response = evaluate_message_with_nlu(message_data)
|
168 |
|
169 |
message_package = return_next_conversational_state(context_data, user_message)
|
170 |
|
mathtext_fastapi/logging.py
ADDED
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
from datetime import datetime
|
3 |
+
|
4 |
+
from dotenv import load_dotenv
|
5 |
+
from supabase import create_client
|
6 |
+
|
7 |
+
load_dotenv()
|
8 |
+
|
9 |
+
SUPA = create_client(os.environ.get('SUPABASE_URL'), os.environ.get('SUPABASE_KEY'))
|
10 |
+
|
11 |
+
|
12 |
+
def log_message_data_through_supabase_api(table_name, log_data):
|
13 |
+
return SUPA.table(table_name).insert(log_data).execute()
|
14 |
+
|
15 |
+
|
16 |
+
def format_datetime_in_isoformat(dt):
|
17 |
+
return getattr(dt.now(), 'isoformat', lambda x: None)()
|
18 |
+
|
19 |
+
|
20 |
+
def get_or_create_supabase_entry(table_name, insert_data, check_variable=None):
|
21 |
+
""" Checks whether a project or contact exists in the database and adds if one is not found
|
22 |
+
|
23 |
+
Input:
|
24 |
+
- table_name: str- the name of the table in Supabase that is being examined
|
25 |
+
- insert_data: json - the data to insert
|
26 |
+
- check_variable: str/None - the specific field to examine for existing matches
|
27 |
+
|
28 |
+
Result
|
29 |
+
- logged_data - an object with the Supabase data
|
30 |
+
|
31 |
+
"""
|
32 |
+
if table_name == 'contact':
|
33 |
+
resp = SUPA.table('contact').select("*").eq("original_contact_id", insert_data['original_contact_id']).eq("project", insert_data['project']).execute()
|
34 |
+
else:
|
35 |
+
resp = SUPA.table(table_name).select("*").eq(check_variable, insert_data[check_variable]).execute()
|
36 |
+
|
37 |
+
if len(resp.data) == 0:
|
38 |
+
logged_data = log_message_data_through_supabase_api(table_name, insert_data)
|
39 |
+
else:
|
40 |
+
logged_data = resp
|
41 |
+
return logged_data
|
42 |
+
|
43 |
+
|
44 |
+
|
45 |
+
def prepare_message_data_for_logging(message_data, nlu_response):
|
46 |
+
""" Builds the message data for each table and ensures it's logged to the database
|
47 |
+
|
48 |
+
Input:
|
49 |
+
- message_data: an object with the full message data from Turn.io/Whatsapp
|
50 |
+
"""
|
51 |
+
project_data = {
|
52 |
+
'name': "Rori",
|
53 |
+
# Autogenerated fields: id, created_at, modified_at
|
54 |
+
}
|
55 |
+
project_data_log = get_or_create_supabase_entry('project', project_data, 'name')
|
56 |
+
|
57 |
+
contact_data = {
|
58 |
+
'project': project_data_log.data[0]['id'], # FK
|
59 |
+
'original_contact_id': message_data['contact_uuid'],
|
60 |
+
'urn': "",
|
61 |
+
'language_code': "en",
|
62 |
+
'contact_inserted_at': format_datetime_in_isoformat(datetime.now())
|
63 |
+
# Autogenerated fields: id, created_at, modified_at
|
64 |
+
}
|
65 |
+
contact_data_log = get_or_create_supabase_entry('contact', contact_data)
|
66 |
+
|
67 |
+
|
68 |
+
del message_data['author_id']
|
69 |
+
|
70 |
+
message_data = {
|
71 |
+
'contact': contact_data_log.data[0]['id'], # FK
|
72 |
+
'original_message_id': message_data['message_id'],
|
73 |
+
'text': message_data['message_body'],
|
74 |
+
'direction': message_data['message_direction'],
|
75 |
+
'sender_type': message_data['author_type'],
|
76 |
+
'channel_type': "whatsapp / turn.io",
|
77 |
+
'message_inserted_at': message_data['message_inserted_at'],
|
78 |
+
'message_modified_at': message_data['message_updated_at'],
|
79 |
+
'message_sent_at': format_datetime_in_isoformat(datetime.now()),
|
80 |
+
'nlu_response': nlu_response,
|
81 |
+
'request_object': message_data
|
82 |
+
# Autogenerated fields: created_at, modified_at
|
83 |
+
}
|
84 |
+
message_data_log = log_message_data_through_supabase_api('message', message_data)
|
mathtext_fastapi/nlu.py
CHANGED
@@ -1,84 +1,87 @@
|
|
1 |
-
import
|
2 |
-
from
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
|
|
|
|
|
|
|
|
|
|
10 |
|
11 |
|
12 |
-
def
|
13 |
-
|
|
|
|
|
|
|
|
|
14 |
|
15 |
|
16 |
-
def
|
17 |
-
|
|
|
|
|
|
|
|
|
18 |
|
19 |
|
20 |
-
def
|
21 |
-
""" Checks
|
22 |
|
23 |
-
Input
|
24 |
-
-
|
25 |
-
- insert_data: json - the data to insert
|
26 |
-
- check_variable: str/None - the specific field to examine for existing matches
|
27 |
|
28 |
-
|
29 |
-
-
|
30 |
-
|
31 |
"""
|
32 |
-
|
33 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
else:
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
else:
|
40 |
-
logged_data = resp
|
41 |
-
return logged_data
|
42 |
|
|
|
|
|
43 |
|
44 |
|
45 |
-
def prepare_message_data_for_logging(message_data, nlu_response):
|
46 |
-
""" Builds the message data for each table and ensures it's logged to the database
|
47 |
-
|
48 |
-
Input:
|
49 |
-
- message_data: an object with the full message data from Turn.io/Whatsapp
|
50 |
-
"""
|
51 |
-
project_data = {
|
52 |
-
'name': "Rori",
|
53 |
-
# Autogenerated fields: id, created_at, modified_at
|
54 |
-
}
|
55 |
-
project_data_log = get_or_create_supabase_entry('project', project_data, 'name')
|
56 |
-
|
57 |
-
contact_data = {
|
58 |
-
'project': project_data_log.data[0]['id'], # FK
|
59 |
-
'original_contact_id': message_data['contact_uuid'],
|
60 |
-
'urn': "",
|
61 |
-
'language_code': "en",
|
62 |
-
'contact_inserted_at': format_datetime_in_isoformat(datetime.now())
|
63 |
-
# Autogenerated fields: id, created_at, modified_at
|
64 |
-
}
|
65 |
-
contact_data_log = get_or_create_supabase_entry('contact', contact_data)
|
66 |
-
|
67 |
-
|
68 |
-
del message_data['author_id']
|
69 |
-
|
70 |
-
message_data = {
|
71 |
-
'contact': contact_data_log.data[0]['id'], # FK
|
72 |
-
'original_message_id': message_data['message_id'],
|
73 |
-
'text': message_data['message_body'],
|
74 |
-
'direction': message_data['message_direction'],
|
75 |
-
'sender_type': message_data['author_type'],
|
76 |
-
'channel_type': "whatsapp / turn.io",
|
77 |
-
'message_inserted_at': message_data['message_inserted_at'],
|
78 |
-
'message_modified_at': message_data['message_updated_at'],
|
79 |
-
'message_sent_at': format_datetime_in_isoformat(datetime.now()),
|
80 |
-
'nlu_response': nlu_response,
|
81 |
-
'request_object': message_data
|
82 |
-
# Autogenerated fields: created_at, modified_at
|
83 |
-
}
|
84 |
-
message_data_log = log_message_data_through_supabase_api('message', message_data)
|
|
|
1 |
+
from mathtext_fastapi.logging import prepare_message_data_for_logging
|
2 |
+
from mathtext.sentiment import sentiment
|
3 |
+
from mathtext.text2int import text2int
|
4 |
+
import re
|
5 |
+
|
6 |
+
|
7 |
+
def build_nlu_response_object(type, data, confidence):
|
8 |
+
""" Builds a json object from the result of nlu functions to send back to Turn.io
|
9 |
+
Inputs
|
10 |
+
- type: str - the type of nlu run (integer or sentiment-analysis)
|
11 |
+
- data: str - the student message
|
12 |
+
- confidence: - the nlu confidence score. Integer is ''. Sentiment analysis is a float
|
13 |
+
"""
|
14 |
+
return {'type': type, 'data': data, 'confidence': confidence}
|
15 |
|
16 |
|
17 |
+
def test_for_float_or_int(message_data, message_text):
|
18 |
+
nlu_response = {}
|
19 |
+
if type(message_text) == int or type(message_text) == float:
|
20 |
+
nlu_response = build_nlu_response_object('integer', message_text, '')
|
21 |
+
prepare_message_data_for_logging(message_data, nlu_response)
|
22 |
+
return nlu_response
|
23 |
|
24 |
|
25 |
+
def test_for_number_sequence(message_text_arr, message_data, message_text):
|
26 |
+
nlu_response = {}
|
27 |
+
if all(ele.isdigit() for ele in message_text_arr):
|
28 |
+
nlu_response = build_nlu_response_object('integer', ','.join(message_text_arr), '')
|
29 |
+
prepare_message_data_for_logging(message_data, nlu_response)
|
30 |
+
return nlu_response
|
31 |
|
32 |
|
33 |
+
def run_text2int_on_each_list_item(message_text_arr):
|
34 |
+
""" Checks each item in an array to see if it can be converted to an integer
|
35 |
|
36 |
+
Input
|
37 |
+
- message_text_arr: list - a set of text extracted from the student message
|
|
|
|
|
38 |
|
39 |
+
Output
|
40 |
+
- student_response_arr: list - a set of integers derived from the nlu function
|
|
|
41 |
"""
|
42 |
+
student_response_arr = []
|
43 |
+
for student_response in message_text_arr:
|
44 |
+
int_api_resp = text2int(student_response.lower())
|
45 |
+
student_response_arr.append(int_api_resp)
|
46 |
+
return student_response_arr
|
47 |
+
|
48 |
+
|
49 |
+
def run_sentiment_analysis(message_text):
|
50 |
+
# TODO: Add intent labelling here
|
51 |
+
# TODO: Add logic to determine whether intent labeling or sentiment analysis is more appropriate (probably default to intent labeling)
|
52 |
+
return sentiment(message_text)
|
53 |
+
|
54 |
+
|
55 |
+
def evaluate_message_with_nlu(message_data):
|
56 |
+
message_text = message_data['message_body']
|
57 |
+
message_text_arr = re.split(", |,| ", message_text.strip())
|
58 |
+
|
59 |
+
# TODO: Replace this with appropriate utility function (is_int, is_float, render_int_or_float)
|
60 |
+
nlu_response = test_for_float_or_int(message_data, message_text)
|
61 |
+
if len(nlu_response) > 0:
|
62 |
+
return nlu_response
|
63 |
+
|
64 |
+
# TODO: Replace this with appropriate utility function
|
65 |
+
nlu_response = test_for_number_sequence(message_text_arr, message_data, message_text)
|
66 |
+
if len(nlu_response) > 0:
|
67 |
+
return nlu_response
|
68 |
+
|
69 |
+
student_response_arr = run_text2int_on_each_list_item(message_text_arr)
|
70 |
+
|
71 |
+
# '32202' is text2int's error code for non-integer student answers (ie., "I don't know")
|
72 |
+
# If any part of the list is 32202, sentiment analysis will run
|
73 |
+
# TODO: Need to replace this with logic that recognizes multiple intents (Maybe 36 = "sentiment analysis" & "integer")
|
74 |
+
student_response_arr = run_text2int_on_each_list_item(message_text_arr)
|
75 |
+
if 32202 in student_response_arr:
|
76 |
+
sentiment_api_resp = sentiment(message_text)
|
77 |
+
nlu_response = build_nlu_response_object('sentiment', sentiment_api_resp[0]['label'], sentiment_api_resp[0]['score'])
|
78 |
else:
|
79 |
+
if len(student_response_arr) > 1:
|
80 |
+
nlu_response = build_nlu_response_object('integer', ','.join(str(num) for num in student_response_arr), '' )
|
81 |
+
else:
|
82 |
+
nlu_response = build_nlu_response_object('integer', student_response_arr[0], '')
|
|
|
|
|
|
|
83 |
|
84 |
+
prepare_message_data_for_logging(message_data, nlu_response)
|
85 |
+
return nlu_response
|
86 |
|
87 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
scripts/make_request.py
CHANGED
@@ -1,144 +1,147 @@
|
|
|
|
1 |
import requests
|
2 |
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
#
|
64 |
-
#
|
65 |
-
#
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
#
|
89 |
-
#
|
90 |
-
#
|
91 |
-
|
92 |
-
#
|
93 |
-
|
94 |
-
|
95 |
-
#
|
96 |
-
|
97 |
-
#
|
98 |
-
#
|
99 |
-
#
|
100 |
-
#
|
101 |
-
#
|
102 |
-
|
103 |
-
#
|
104 |
-
|
105 |
-
#
|
106 |
-
|
107 |
-
#
|
108 |
-
#
|
109 |
-
#
|
110 |
-
#
|
111 |
-
#
|
112 |
-
|
113 |
-
#
|
114 |
-
|
115 |
-
#
|
116 |
-
|
117 |
-
#
|
118 |
-
#
|
119 |
-
#
|
120 |
-
#
|
121 |
-
#
|
122 |
-
|
123 |
-
#
|
124 |
-
|
125 |
-
#
|
126 |
-
|
127 |
-
#
|
128 |
-
#
|
129 |
-
#
|
130 |
-
#
|
131 |
-
#
|
132 |
-
|
133 |
-
#
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
|
|
|
|
|
1 |
+
import json
|
2 |
import requests
|
3 |
|
4 |
+
|
5 |
+
def add_message_text_to_sample_object(message_text):
|
6 |
+
"""
|
7 |
+
Builds a sample request object using an example of a student answer
|
8 |
+
|
9 |
+
Input
|
10 |
+
- message_text: str - an example of user input to test
|
11 |
+
|
12 |
+
Example Input
|
13 |
+
"test message"
|
14 |
+
|
15 |
+
Output
|
16 |
+
- b_string: json b-string - an object simulating what Turn.io sends to the API endpoint using the message_text
|
17 |
+
|
18 |
+
Example Output
|
19 |
+
b'{"context": "hi", "message_data": {"author_id": "+57787919091", "author_type": "OWNER", "contact_uuid": "j43hk26-2hjl-43jk-hnk2-k4ljl46j0ds09", "message_body": "test message", "message_direction": "inbound", "message_id": "4kl209sd0-a7b8-2hj3-8563-3hu4a89b32", "message_inserted_at": "2023-01-10T02:37:28.477940Z", "message_updated_at": "2023-01-10T02:37:28.487319Z"}}'
|
20 |
+
|
21 |
+
"""
|
22 |
+
message_data = '{' + f'"author_id": "+57787919091", "author_type": "OWNER", "contact_uuid": "j43hk26-2hjl-43jk-hnk2-k4ljl46j0ds09", "message_body": "{message_text}", "message_direction": "inbound", "message_id": "4kl209sd0-a7b8-2hj3-8563-3hu4a89b32", "message_inserted_at": "2023-01-10T02:37:28.477940Z", "message_updated_at": "2023-01-10T02:37:28.487319Z"' + '}'
|
23 |
+
context_data = '{' + '"user":"", "state":"start-conversation", "bot_message":"", "user_message":"{message_text}"' + '}'
|
24 |
+
|
25 |
+
json_string = '{' + f'"context_data": {context_data}, "message_data": {message_data}' + '}'
|
26 |
+
b_string = json_string.encode("utf-8")
|
27 |
+
|
28 |
+
return b_string
|
29 |
+
|
30 |
+
|
31 |
+
def run_simulated_request(endpoint, sample_answer, context = None):
|
32 |
+
print(f"Case: {sample_answer}")
|
33 |
+
b_string = add_message_text_to_sample_object(sample_answer)
|
34 |
+
|
35 |
+
if endpoint == 'sentiment-analysis' or endpoint == 'text2int':
|
36 |
+
request = requests.post(url=
|
37 |
+
f'http://localhost:7860/{endpoint}',
|
38 |
+
json={'content': sample_answer}
|
39 |
+
).json()
|
40 |
+
else:
|
41 |
+
request = requests.post(url=
|
42 |
+
f'http://localhost:7860/{endpoint}',
|
43 |
+
data=b_string
|
44 |
+
).json()
|
45 |
+
|
46 |
+
print(request)
|
47 |
+
|
48 |
+
run_simulated_request('sentiment-analysis', 'I reject it')
|
49 |
+
run_simulated_request('text2int', 'seven thousand nine hundred fifty seven')
|
50 |
+
run_simulated_request('nlu', 'test message')
|
51 |
+
run_simulated_request('nlu', 'eight')
|
52 |
+
run_simulated_request('nlu', 'eight, nine, ten')
|
53 |
+
run_simulated_request('nlu', '8, 9, 10')
|
54 |
+
run_simulated_request('nlu', '8')
|
55 |
+
run_simulated_request('nlu', "I don't know")
|
56 |
+
run_simulated_request('nlu', 'Today is a wonderful day')
|
57 |
+
run_simulated_request('nlu', 'IDK 5?')
|
58 |
+
run_simulated_request('manager', '')
|
59 |
+
run_simulated_request('manager', 'add')
|
60 |
+
run_simulated_request('manager', 'subtract')
|
61 |
+
run_simulated_request('manager', 'exit')
|
62 |
+
|
63 |
+
|
64 |
+
# Example of simplified object received from Turn.io stacks
|
65 |
+
# This is a contrived example to show the structure, not an actual state
|
66 |
+
# NOTE: This is actually a bstring, not a dict
|
67 |
+
simplified_json = {
|
68 |
+
"context": {
|
69 |
+
"user":"+57787919091",
|
70 |
+
"state":"answer-addition-problem",
|
71 |
+
"bot_message":"What is 2+2?",
|
72 |
+
"user_message":"eight",
|
73 |
+
"type": "ask"
|
74 |
+
},
|
75 |
+
"message_data": {
|
76 |
+
"author_id": "+57787919091",
|
77 |
+
"author_type": "OWNER",
|
78 |
+
"contact_uuid": "j43hk26-2hjl-43jk-hnk2-k4ljl46j0ds09",
|
79 |
+
"message_body": "eight",
|
80 |
+
"message_direction": "inbound",
|
81 |
+
"message_id": "4kl209sd0-a7b8-2hj3-8563-3hu4a89b32",
|
82 |
+
"message_inserted_at": "2023-01-10T02:37:28.477940Z",
|
83 |
+
"message_updated_at": "2023-01-10T02:37:28.487319Z"
|
84 |
+
}
|
85 |
+
}
|
86 |
+
|
87 |
+
|
88 |
+
|
89 |
+
# Full example of event data from Turn.io
|
90 |
+
# simplified_json is built from this in Turn.io
|
91 |
+
# full_json = {
|
92 |
+
# 'message': {
|
93 |
+
# '_vnd': {
|
94 |
+
# 'v1': {
|
95 |
+
# 'author': {
|
96 |
+
# 'id': 57787919091,
|
97 |
+
# 'name': 'GT',
|
98 |
+
# 'type': 'OWNER'
|
99 |
+
# },
|
100 |
+
# 'card_uuid': None,
|
101 |
+
# 'chat': {
|
102 |
+
# 'assigned_to': {
|
103 |
+
# 'id': 'jhk151kl-hj42-3752-3hjk-h4jk6hjkk2',
|
104 |
+
# 'name': 'Greg Thompson',
|
105 |
+
# 'type': 'OPERATOR'
|
106 |
+
# },
|
107 |
+
# 'contact_uuid': 'j43hk26-2hjl-43jk-hnk2-k4ljl46j0ds09',
|
108 |
+
# 'inserted_at': '2022-07-05T04:00:34.033522Z',
|
109 |
+
# 'owner': '+57787919091',
|
110 |
+
# 'permalink': 'https://app.turn.io/c/4kl209sd0-a7b8-2hj3-8563-3hu4a89b32',
|
111 |
+
# 'state': 'OPEN',
|
112 |
+
# 'state_reason': 'Re-opened by inbound message.',
|
113 |
+
# 'unread_count': 19,
|
114 |
+
# 'updated_at': '2023-01-10T02:37:28.487319Z',
|
115 |
+
# 'uuid': '4kl209sd0-a7b8-2hj3-8563-3hu4a89b32'
|
116 |
+
# },
|
117 |
+
# 'direction': 'inbound',
|
118 |
+
# 'faq_uuid': None,
|
119 |
+
# 'in_reply_to': None,
|
120 |
+
# 'inserted_at': '2023-01-10T02:37:28.477940Z',
|
121 |
+
# 'labels': [{
|
122 |
+
# 'confidence': 0.506479332,
|
123 |
+
# 'metadata': {
|
124 |
+
# 'nlu': {
|
125 |
+
# 'confidence': 0.506479332,
|
126 |
+
# 'intent': 'question',
|
127 |
+
# 'model_name': 'nlu-general-spacy-ngrams-20191014'
|
128 |
+
# }
|
129 |
+
# },
|
130 |
+
# 'uuid': 'ha7890s2k-hjk2-2476-s8d9-fh9779a8a9ds',
|
131 |
+
# 'value': 'Unclassified'
|
132 |
+
# }],
|
133 |
+
# 'last_status': None,
|
134 |
+
# 'last_status_timestamp': None,
|
135 |
+
# 'on_fallback_channel': False,
|
136 |
+
# 'rendered_content': None,
|
137 |
+
# 'uuid': 's8df79zhws-h89s-hj23-7s8d-thb248d9bh2qn'
|
138 |
+
# }
|
139 |
+
# },
|
140 |
+
# 'from': 57787919091,
|
141 |
+
# 'id': 'hsjkthzZGehkzs09sijWA3',
|
142 |
+
# 'text': {'body': 'eight'},
|
143 |
+
# 'timestamp': 1673318248,
|
144 |
+
# 'type': 'text'
|
145 |
+
# },
|
146 |
+
# 'type': 'message'
|
147 |
+
# }
|