Hobson commited on
Commit
e519286
1 Parent(s): 3260908

nlu assertions to log error messages for all possible errors in payload data format

Browse files
mathtext_fastapi/conversation_manager.py CHANGED
@@ -39,6 +39,7 @@ def create_text_message(message_text, whatsapp_id):
39
  "preview_url": False,
40
  "recipient_type": "individual",
41
  "to": whatsapp_id,
 
42
  "type": "text",
43
  "text": {
44
  "body": message_text
@@ -136,6 +137,9 @@ def manage_math_quiz_fsm(user_message, contact_uuid, type):
136
 
137
  # Make a completely new entry
138
  if fsm_check.data == []:
 
 
 
139
  if type == 'addition':
140
  math_quiz_state_machine = MathQuizFSM()
141
  else:
 
39
  "preview_url": False,
40
  "recipient_type": "individual",
41
  "to": whatsapp_id,
42
+ # FIXME: Better to use "message_type" (but be careful with refactor)
43
  "type": "text",
44
  "text": {
45
  "body": message_text
 
137
 
138
  # Make a completely new entry
139
  if fsm_check.data == []:
140
+ # FIXME: Try not to use the Python reserved keyword `type` as a variable name
141
+ # It's better to use `kind` or `convo_type` or `convo_name`
142
+ # And the variable `type` is not defined here so I don't understand how this is working at all.
143
  if type == 'addition':
144
  math_quiz_state_machine = MathQuizFSM()
145
  else:
mathtext_fastapi/nlu.py CHANGED
@@ -1,23 +1,20 @@
1
  from collections.abc import Mapping
2
  from logging import getLogger
3
  import datetime as dt
4
- import re
5
 
6
  from fuzzywuzzy import fuzz
7
  from mathtext_fastapi.logging import prepare_message_data_for_logging
8
  from mathtext.sentiment import sentiment
9
- from mathtext.text2int import text2int
10
- from mathtext_fastapi.intent_classification import create_intent_classification_model, retrieve_intent_classification_model, predict_message_intent
11
 
12
  log = getLogger(__name__)
13
 
14
- ERROR_CODE = 32202
15
 
16
-
17
- def build_nlu_response_object(type, data, confidence):
18
  """ Turns nlu results into an object to send back to Turn.io
19
  Inputs
20
- - type: str - the type of nlu run (integer or sentiment-analysis)
21
  - data: str/int - the student message
22
  - confidence: - the nlu confidence score (sentiment) or '' (integer)
23
 
@@ -27,7 +24,11 @@ def build_nlu_response_object(type, data, confidence):
27
  >>> build_nlu_response_object('sentiment', 'POSITIVE', 0.99)
28
  {'type': 'sentiment', 'data': 'POSITIVE', 'confidence': 0.99}
29
  """
30
- return {'type': type, 'data': data, 'confidence': confidence}
 
 
 
 
31
 
32
 
33
  # def test_for_float_or_int(message_data, message_text):
@@ -167,6 +168,86 @@ def payload_is_valid(payload_object):
167
  )
168
  )
169
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170
 
171
  def evaluate_message_with_nlu(message_data):
172
  """ Process a student's message using NLU functions and send the result
@@ -182,14 +263,15 @@ def evaluate_message_with_nlu(message_data):
182
  log.info(f'Starting evaluate message: {message_data}')
183
 
184
  if not payload_is_valid(message_data):
185
- return {'type': 'error', 'data': ERROR_CODE, 'confidence': 0}
 
186
 
187
  try:
188
  message_text = str(message_data.get('message_body', ''))
189
  except:
190
  log.error(f'Invalid request payload: {message_data}')
191
  # use python logging system to do this//
192
- return {'type': 'error', 'data': ERROR_CODE, 'confidence': 0}
193
 
194
  # Run intent classification only for keywords
195
  intent_api_response = run_intent_classification(message_text)
@@ -199,7 +281,7 @@ def evaluate_message_with_nlu(message_data):
199
 
200
  number_api_resp = text2int(message_text.lower())
201
 
202
- if number_api_resp == ERROR_CODE:
203
  # Run intent classification with logistic regression model
204
  predicted_label = predict_message_intent(message_text)
205
  if predicted_label['confidence'] > 0.01:
 
1
  from collections.abc import Mapping
2
  from logging import getLogger
3
  import datetime as dt
 
4
 
5
  from fuzzywuzzy import fuzz
6
  from mathtext_fastapi.logging import prepare_message_data_for_logging
7
  from mathtext.sentiment import sentiment
8
+ from mathtext.text2int import text2int, TOKENS2INT_ERROR_INT
9
+ from mathtext_fastapi.intent_classification import predict_message_intent
10
 
11
  log = getLogger(__name__)
12
 
 
13
 
14
+ def build_nlu_response_object(nlu_type, data, confidence):
 
15
  """ Turns nlu results into an object to send back to Turn.io
16
  Inputs
17
+ - nlu_type: str - the type of nlu run (integer or sentiment-analysis)
18
  - data: str/int - the student message
19
  - confidence: - the nlu confidence score (sentiment) or '' (integer)
20
 
 
24
  >>> build_nlu_response_object('sentiment', 'POSITIVE', 0.99)
25
  {'type': 'sentiment', 'data': 'POSITIVE', 'confidence': 0.99}
26
  """
27
+ return {
28
+ 'type': nlu_type,
29
+ 'data': data,
30
+ 'confidence': confidence
31
+ }
32
 
33
 
34
  # def test_for_float_or_int(message_data, message_text):
 
168
  )
169
  )
170
 
171
+ def log_payload_errors(payload_object):
172
+ errors = []
173
+ try:
174
+ assert isinstance(payload_object, Mapping)
175
+ except Exception as e:
176
+ log.error(f'Invalid HTTP request payload object: {e}')
177
+ errors.append(e)
178
+ try:
179
+ assert isinstance(payload_object.get('author_id'), str)
180
+ except Exception as e:
181
+ log.error(f'Invalid HTTP request payload object: {e}')
182
+ errors.append(e)
183
+ try:
184
+ assert isinstance(payload_object.get('author_type'), str)
185
+ except Exception as e:
186
+ log.error(f'Invalid HTTP request payload object: {e}')
187
+ errors.append(e)
188
+ try:
189
+ assert isinstance(payload_object.get('contact_uuid'), str)
190
+ except Exception as e:
191
+ log.error(f'Invalid HTTP request payload object: {e}')
192
+ errors.append(e)
193
+ try:
194
+ assert isinstance(payload_object.get('message_body'), str)
195
+ except Exception as e:
196
+ log.error(f'Invalid HTTP request payload object: {e}')
197
+ errors.append(e)
198
+ try:
199
+ assert isinstance(payload_object.get('message_direction'), str)
200
+ except Exception as e:
201
+ log.error(f'Invalid HTTP request payload object: {e}')
202
+ errors.append(e)
203
+ try:
204
+ assert isinstance(payload_object.get('inbound'), str)
205
+ except Exception as e:
206
+ log.error(f'Invalid HTTP request payload object: {e}')
207
+ errors.append(e)
208
+ try:
209
+ assert isinstance(payload_object.get('message_id'), str)
210
+ except Exception as e:
211
+ log.error(f'Invalid HTTP request payload object: {e}')
212
+ errors.append(e)
213
+ try:
214
+ assert isinstance(payload_object.get('message_inserted_at'), str)
215
+ except Exception as e:
216
+ log.error(f'Invalid HTTP request payload object: {e}')
217
+ errors.append(e)
218
+ try:
219
+ assert isinstance(payload_object.get('message_updated_at'), str)
220
+ except Exception as e:
221
+ log.error(f'Invalid HTTP request payload object: {e}')
222
+ errors.append(e)
223
+ try:
224
+ assert isinstance(payload_object.get('message_inserted_at'), str)
225
+ except Exception as e:
226
+ log.error(f'Invalid HTTP request payload object: {e}')
227
+ errors.append(e)
228
+ try:
229
+ assert isinstance(payload_object.get('message_updated_at'), str)
230
+ except Exception as e:
231
+ log.error(f'Invalid HTTP request payload object: {e}')
232
+ errors.append(e)
233
+ try:
234
+ assert isinstance(
235
+ dt.datetime.fromisoformat(payload_object.get('message_inserted_at')),
236
+ dt.datetime
237
+ )
238
+ except Exception as e:
239
+ log.error(f'Invalid HTTP request payload object: {e}')
240
+ errors.append(e)
241
+ try:
242
+ isinstance(
243
+ dt.datetime.fromisoformat(payload_object.get('message_updated_at')),
244
+ dt.datetime
245
+ )
246
+ except Exception as e:
247
+ log.error(f'Invalid HTTP request payload object: {e}')
248
+ errors.append(e)
249
+ return errors
250
+
251
 
252
  def evaluate_message_with_nlu(message_data):
253
  """ Process a student's message using NLU functions and send the result
 
263
  log.info(f'Starting evaluate message: {message_data}')
264
 
265
  if not payload_is_valid(message_data):
266
+ log_payload_errors(message_data)
267
+ return {'type': 'error', 'data': TOKENS2INT_ERROR_INT, 'confidence': 0}
268
 
269
  try:
270
  message_text = str(message_data.get('message_body', ''))
271
  except:
272
  log.error(f'Invalid request payload: {message_data}')
273
  # use python logging system to do this//
274
+ return {'type': 'error', 'data': TOKENS2INT_ERROR_INT, 'confidence': 0}
275
 
276
  # Run intent classification only for keywords
277
  intent_api_response = run_intent_classification(message_text)
 
281
 
282
  number_api_resp = text2int(message_text.lower())
283
 
284
+ if number_api_resp == TOKENS2INT_ERROR_INT:
285
  # Run intent classification with logistic regression model
286
  predicted_label = predict_message_intent(message_text)
287
  if predicted_label['confidence'] > 0.01: