Greg Thompson commited on
Commit
5baf30a
2 Parent(s): 1cf9a85 227c7f2

Merge branch vlad into main

Browse files
.env.sample ADDED
@@ -0,0 +1 @@
 
 
1
+ SENTRY_URL=<sentry_url>
CHANGELOG.md ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ ## [0.0.12](https://gitlab.com/tangibleai/community/mathtext-fastapi/-/tags/0.0.12)
3
+
4
+ Improve NLU capabilities
5
+ - Improved handling for integers (1), floats (1.0), and text numbers (one)
6
+ - Integrates fuzzy keyword matching for 'easier', 'exit', 'harder', 'hint', 'next', 'stop'
7
+ - Integrates intent classification for user messages
8
+ - Improved conversation management system
9
+ - Created a data-driven quiz prototype
10
+
11
+
12
+ ## [0.0.0](https://gitlab.com/tangibleai/community/mathtext-fastapi/-/tags/0.0.0)
13
+
14
+ Initial release
15
+ - Basic text to integer NLU evaluation of user responses
16
+ - Basic sentiment analysis evaluation of user responses
17
+ - Prototype conversation manager using finite state machines
18
+ - Support for logging of user message data
app.py CHANGED
@@ -4,7 +4,10 @@ or
4
  `python -m uvicorn app:app --reload --host localhost --port 7860`
5
  """
6
  import ast
 
7
  import mathactive.microlessons.num_one as num_one_quiz
 
 
8
  from fastapi import FastAPI, Request
9
  from fastapi.responses import JSONResponse
10
  from fastapi.staticfiles import StaticFiles
@@ -18,6 +21,22 @@ from mathtext_fastapi.conversation_manager import manage_conversation_response
18
  from mathtext_fastapi.v2_conversation_manager import manage_conversation_response
19
  from mathtext_fastapi.nlu import evaluate_message_with_nlu
20
  from mathtext_fastapi.nlu import run_intent_classification
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
  app = FastAPI()
23
 
@@ -35,6 +54,11 @@ def home(request: Request):
35
  return templates.TemplateResponse("home.html", {"request": request})
36
 
37
 
 
 
 
 
 
38
  @app.post("/hello")
39
  def hello(content: Text = None):
40
  content = {"message": f"Hello {content.content}!"}
@@ -164,7 +188,7 @@ async def num_one(request: Request):
164
  """
165
  print("STEP 1")
166
  data_dict = await request.json()
167
- message_data = ast.literal_eval(data_dict.get('message_data', '').get('message_body', ''))
168
  user_id = message_data['user_id']
169
  message_text = message_data['message_text']
170
  print("STEP 2")
 
4
  `python -m uvicorn app:app --reload --host localhost --port 7860`
5
  """
6
  import ast
7
+ import json
8
  import mathactive.microlessons.num_one as num_one_quiz
9
+ import os
10
+ import sentry_sdk
11
  from fastapi import FastAPI, Request
12
  from fastapi.responses import JSONResponse
13
  from fastapi.staticfiles import StaticFiles
 
21
  from mathtext_fastapi.v2_conversation_manager import manage_conversation_response
22
  from mathtext_fastapi.nlu import evaluate_message_with_nlu
23
  from mathtext_fastapi.nlu import run_intent_classification
24
+ from dotenv import load_dotenv
25
+ from sentry_sdk.utils import BadDsn
26
+
27
+ load_dotenv()
28
+
29
+ try:
30
+ sentry_sdk.init(
31
+ dsn=os.environ.get('SENTRY_DNS'),
32
+
33
+ # Set traces_sample_rate to 1.0 to capture 100%
34
+ # of transactions for performance monitoring.
35
+ # We recommend adjusting this value in production,
36
+ traces_sample_rate=0.20,
37
+ )
38
+ except BadDsn:
39
+ pass
40
 
41
  app = FastAPI()
42
 
 
54
  return templates.TemplateResponse("home.html", {"request": request})
55
 
56
 
57
+ @app.get("/sentry-debug")
58
+ async def trigger_error():
59
+ division_by_zero = 1 / 0
60
+
61
+
62
  @app.post("/hello")
63
  def hello(content: Text = None):
64
  content = {"message": f"Hello {content.content}!"}
 
188
  """
189
  print("STEP 1")
190
  data_dict = await request.json()
191
+ message_data = json.loads(data_dict.get('message_data', '').get('message_body', '').replace("'", '"'))
192
  user_id = message_data['user_id']
193
  message_text = message_data['message_text']
194
  print("STEP 2")
mathtext_fastapi/intent_classification.py CHANGED
@@ -41,9 +41,13 @@ def retrieve_intent_classification_model():
41
  return model
42
 
43
 
 
 
 
 
 
 
44
  def predict_message_intent(message):
45
- encoder = SentenceTransformer('all-MiniLM-L6-v2')
46
- model = retrieve_intent_classification_model()
47
  tokenized_utterance = np.array([list(encoder.encode(message))])
48
  predicted_label = model.predict(tokenized_utterance)
49
  predicted_probabilities = model.predict_proba(tokenized_utterance)
 
41
  return model
42
 
43
 
44
+ encoder = SentenceTransformer('all-MiniLM-L6-v2')
45
+ # model = retrieve_intent_classification_model()
46
+ DATA_DIR = Path(__file__).parent.parent / "mathtext_fastapi" / "data" / "intent_classification_model.joblib"
47
+ model = load(DATA_DIR)
48
+
49
+
50
  def predict_message_intent(message):
 
 
51
  tokenized_utterance = np.array([list(encoder.encode(message))])
52
  predicted_label = model.predict(tokenized_utterance)
53
  predicted_probabilities = model.predict_proba(tokenized_utterance)
mathtext_fastapi/nlu.py CHANGED
@@ -110,7 +110,10 @@ def run_intent_classification(message_text):
110
  ]
111
 
112
  for command in commands:
113
- ratio = fuzz.ratio(command, message_text.lower())
 
 
 
114
  if ratio > 80:
115
  nlu_response['data'] = command
116
  nlu_response['confidence'] = ratio / 100
@@ -129,7 +132,7 @@ def evaluate_message_with_nlu(message_data):
129
  """
130
  # Keeps system working with two different inputs - full and filtered @event object
131
  try:
132
- message_text = message_data['message_body']
133
  except KeyError:
134
  message_data = {
135
  'author_id': message_data['message']['_vnd']['v1']['chat']['owner'],
@@ -141,11 +144,12 @@ def evaluate_message_with_nlu(message_data):
141
  'message_inserted_at': message_data['message']['_vnd']['v1']['chat']['inserted_at'],
142
  'message_updated_at': message_data['message']['_vnd']['v1']['chat']['updated_at'],
143
  }
144
- message_text = message_data['message_body']
145
 
146
  # Run intent classification only for keywords
147
  intent_api_response = run_intent_classification(message_text)
148
  if intent_api_response['data']:
 
149
  return intent_api_response
150
 
151
  number_api_resp = text2int(message_text.lower())
 
110
  ]
111
 
112
  for command in commands:
113
+ try:
114
+ ratio = fuzz.ratio(command, message_text.lower())
115
+ except:
116
+ ratio = 0
117
  if ratio > 80:
118
  nlu_response['data'] = command
119
  nlu_response['confidence'] = ratio / 100
 
132
  """
133
  # Keeps system working with two different inputs - full and filtered @event object
134
  try:
135
+ message_text = str(message_data['message_body'])
136
  except KeyError:
137
  message_data = {
138
  'author_id': message_data['message']['_vnd']['v1']['chat']['owner'],
 
144
  'message_inserted_at': message_data['message']['_vnd']['v1']['chat']['inserted_at'],
145
  'message_updated_at': message_data['message']['_vnd']['v1']['chat']['updated_at'],
146
  }
147
+ message_text = str(message_data['message_body'])
148
 
149
  # Run intent classification only for keywords
150
  intent_api_response = run_intent_classification(message_text)
151
  if intent_api_response['data']:
152
+ prepare_message_data_for_logging(message_data, intent_api_response)
153
  return intent_api_response
154
 
155
  number_api_resp = text2int(message_text.lower())
pyproject.toml CHANGED
@@ -31,6 +31,7 @@ supabase = "*"
31
  uvicorn = "0.17.*"
32
  pandas = "^1.5.3"
33
  scipy = "^1.10.1"
 
34
 
35
  [tool.poetry.group.dev.dependencies]
36
  pytest = "^7.2"
 
31
  uvicorn = "0.17.*"
32
  pandas = "^1.5.3"
33
  scipy = "^1.10.1"
34
+ sentry_sdk = "^1.19.1"
35
 
36
  [tool.poetry.group.dev.dependencies]
37
  pytest = "^7.2"
requirements.txt CHANGED
@@ -3,7 +3,7 @@ en-core-web-sm @ https://github.com/explosion/spacy-models/releases/download/en_
3
  fuzzywuzzy
4
  jsonpickle
5
  mathtext @ git+https://gitlab.com/tangibleai/community/mathtext@main
6
- mathactive @ git+https://gitlab.com/tangibleai/community/mathactive@main
7
  fastapi
8
  pydantic
9
  requests
@@ -11,6 +11,7 @@ sentencepiece
11
  openpyxl
12
  python-Levenshtein
13
  sentence-transformers
 
14
  supabase
15
  transitions
16
  uvicorn
 
3
  fuzzywuzzy
4
  jsonpickle
5
  mathtext @ git+https://gitlab.com/tangibleai/community/mathtext@main
6
+ mathactive @ git+https://gitlab.com/tangibleai/community/mathactive@vlad
7
  fastapi
8
  pydantic
9
  requests
 
11
  openpyxl
12
  python-Levenshtein
13
  sentence-transformers
14
+ sentry-sdk[fastapi]
15
  supabase
16
  transitions
17
  uvicorn
scripts/env_loader.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import dotenv
2
+ import os
3
+
4
+ dotenv.load_dotenv(".env")
5
+ envs = {}
6
+
7
+
8
+ for var in ["SENTRY_URL"]:
9
+ envs[var] = os.getenv(var)
scripts/logger.py ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sentry_sdk
2
+ from . import env_loader
3
+
4
+ sentry_sdk.init(
5
+ dsn=env_loader.envs.get("SENTRY_URL"),
6
+
7
+ # Set traces_sample_rate to 1.0 to capture 100%
8
+ # of transactions for performance monitoring.
9
+ # We recommend adjusting this value in production.
10
+ traces_sample_rate=1.0
11
+ )
scripts/make_request.py CHANGED
@@ -66,21 +66,19 @@ def run_simulated_request(endpoint, sample_answer, context=None):
66
  # run_simulated_request('intent-classification', "I'm not sure")
67
  # run_simulated_request('sentiment-analysis', 'I reject it')
68
  # run_simulated_request('text2int', 'seven thousand nine hundred fifty seven')
69
- # run_simulated_request('nlu', 'test message')
70
- # run_simulated_request('nlu', 'eight')
71
- # run_simulated_request('nlu', 'is it 8')
72
- # run_simulated_request('nlu', 'can I know how its 0.5')
73
- # run_simulated_request('nlu', 'eight, nine, ten')
74
- # run_simulated_request('nlu', '8, 9, 10')
75
- # run_simulated_request('nlu', '8')
76
- # run_simulated_request('nlu', "I don't know")
77
- # run_simulated_request('nlu', "I don't know eight")
78
- # run_simulated_request('nlu', "I don't 9")
79
- # run_simulated_request('nlu', "0.2")
80
- # run_simulated_request('nlu', 'Today is a wonderful day')
81
- # run_simulated_request('nlu', 'IDK 5?')
82
- # run_simulated_request('v2/manager', '')
83
- # run_simulated_request('v2/manager', '5')
84
  # run_simulated_request('manager', '')
85
  # run_simulated_request('manager', 'add')
86
  # run_simulated_request('manager', 'subtract')
 
66
  # run_simulated_request('intent-classification', "I'm not sure")
67
  # run_simulated_request('sentiment-analysis', 'I reject it')
68
  # run_simulated_request('text2int', 'seven thousand nine hundred fifty seven')
69
+ run_simulated_request('nlu', 'test message')
70
+ run_simulated_request('nlu', 'eight')
71
+ run_simulated_request('nlu', 'is it 8')
72
+ run_simulated_request('nlu', 'can I know how its 0.5')
73
+ run_simulated_request('nlu', 'eight, nine, ten')
74
+ run_simulated_request('nlu', '8, 9, 10')
75
+ run_simulated_request('nlu', '8')
76
+ run_simulated_request('nlu', "I don't know")
77
+ run_simulated_request('nlu', "I don't know eight")
78
+ run_simulated_request('nlu', "I don't 9")
79
+ run_simulated_request('nlu', "0.2")
80
+ run_simulated_request('nlu', 'Today is a wonderful day')
81
+ run_simulated_request('nlu', 'IDK 5?')
 
 
82
  # run_simulated_request('manager', '')
83
  # run_simulated_request('manager', 'add')
84
  # run_simulated_request('manager', 'subtract')