Spaces:
Runtime error
Runtime error
Merge branch 'turnio-integration' into 'main'
Browse filesAdd Turn API and logging support
See merge request tangibleai/community/mathtext-fastapi!1
- app.py +30 -0
- modules/nlu.py +54 -0
- requirements.txt +3 -0
- scripts/make_request.py +66 -0
app.py
CHANGED
@@ -10,6 +10,7 @@ from pydantic import BaseModel
|
|
10 |
|
11 |
from modules.sentiment import sentiment
|
12 |
from modules.text2int import text2int
|
|
|
13 |
# FIXME:
|
14 |
# from mathtext.text2int import text2int
|
15 |
|
@@ -47,3 +48,32 @@ def text2int_ep(content: Text = None):
|
|
47 |
ml_response = text2int(content.content)
|
48 |
content = {"message": ml_response}
|
49 |
return JSONResponse(content=content)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
|
11 |
from modules.sentiment import sentiment
|
12 |
from modules.text2int import text2int
|
13 |
+
from modules.nlu import prepare_message_data_for_logging
|
14 |
# FIXME:
|
15 |
# from mathtext.text2int import text2int
|
16 |
|
|
|
48 |
ml_response = text2int(content.content)
|
49 |
content = {"message": ml_response}
|
50 |
return JSONResponse(content=content)
|
51 |
+
|
52 |
+
@app.post("/nlu")
|
53 |
+
async def evaluate_user_message_with_nlu_api(request: Request):
|
54 |
+
""" Calls NLU APIs on the most recent user message from Turn.io message data and logs the message data
|
55 |
+
|
56 |
+
Input
|
57 |
+
- request.body: a json object of message data for the most recent user response
|
58 |
+
|
59 |
+
Output
|
60 |
+
- int_data_dict or sent_data_dict: A dictionary telling the type of NLU run and the resulting data
|
61 |
+
{'type':'integer', 'data': '8'}
|
62 |
+
{'type':'sentiment', 'data': 'negative'}
|
63 |
+
"""
|
64 |
+
|
65 |
+
message_data = await request.json()
|
66 |
+
message_text = message_data['message']['text']['body'].lower()
|
67 |
+
|
68 |
+
int_api_resp = text2int(message_text)
|
69 |
+
|
70 |
+
if int_api_resp == '32202':
|
71 |
+
sentiment_api_resp = sentiment(message_text)
|
72 |
+
# [{'label': 'POSITIVE', 'score': 0.991188645362854}]
|
73 |
+
sent_data_dict = {'type': 'sentiment', 'data': sentiment_api_resp[0]['label']}
|
74 |
+
return JSONResponse(content={'type': 'sentiment', 'data': 'negative'})
|
75 |
+
|
76 |
+
prepare_message_data_for_logging(message_data)
|
77 |
+
|
78 |
+
int_data_dict = {'type': 'integer', 'data': int_api_resp}
|
79 |
+
return JSONResponse(content=int_data_dict)
|
modules/nlu.py
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import environ
|
2 |
+
import json
|
3 |
+
import os
|
4 |
+
import requests
|
5 |
+
|
6 |
+
from datetime import datetime
|
7 |
+
from supabase import create_client
|
8 |
+
|
9 |
+
|
10 |
+
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
11 |
+
env = environ.Env()
|
12 |
+
env_path = os.path.join(BASE_DIR, '.env')
|
13 |
+
environ.Env.read_env('.env')
|
14 |
+
|
15 |
+
SUPA = create_client(env('SUPABASE_URL'), env('SUPABASE_KEY'))
|
16 |
+
|
17 |
+
def log_message_data_through_supabase_api(table_name, log_data):
|
18 |
+
return SUPA.table(table_name).insert(log_data).execute()
|
19 |
+
|
20 |
+
|
21 |
+
def format_datetime_in_isoformat(dt):
|
22 |
+
return getattr(dt.now(), 'isoformat', lambda x: None)()
|
23 |
+
|
24 |
+
|
25 |
+
def prepare_message_data_for_logging(message_data):
|
26 |
+
project_data = {
|
27 |
+
'name': "turn.io",
|
28 |
+
# Autogenerated fields: id, created_at, modified_at
|
29 |
+
}
|
30 |
+
project_data_log = log_message_data_through_supabase_api('project', project_data)
|
31 |
+
|
32 |
+
contact_data = {
|
33 |
+
'project': project_data_log.data[0]['id'], # FK
|
34 |
+
'original_contact_id': message_data['message']['_vnd']['v1']['chat']['contact_uuid'],
|
35 |
+
'urn': "",
|
36 |
+
'language_code': "en",
|
37 |
+
'contact_inserted_at': format_datetime_in_isoformat(datetime.now())
|
38 |
+
# Autogenerated fields: id, created_at, modified_at
|
39 |
+
}
|
40 |
+
contact_data_log = log_message_data_through_supabase_api('contact', contact_data)
|
41 |
+
|
42 |
+
message_data = {
|
43 |
+
'contact': contact_data_log.data[0]['id'], # FK
|
44 |
+
'original_message_id': message_data['message']['id'],
|
45 |
+
'text': message_data['message']['text']['body'],
|
46 |
+
'direction': message_data['message']['_vnd']['v1']['direction'],
|
47 |
+
'sender_type': message_data['message']['_vnd']['v1']['author']['type'],
|
48 |
+
'channel_type': "whatsapp / turn.io",
|
49 |
+
'message_inserted_at': message_data['message']['_vnd']['v1']['chat']['inserted_at'],
|
50 |
+
'message_modified_at': message_data['message']['_vnd']['v1']['chat']['updated_at'],
|
51 |
+
'message_sent_at': format_datetime_in_isoformat(datetime.now())
|
52 |
+
# Autogenerated fields: created_at, modified_at
|
53 |
+
}
|
54 |
+
message_data_log = log_message_data_through_supabase_api('message', message_data)
|
requirements.txt
CHANGED
@@ -10,3 +10,6 @@ pandas
|
|
10 |
matplotlib
|
11 |
pytest
|
12 |
httpx
|
|
|
|
|
|
|
|
10 |
matplotlib
|
11 |
pytest
|
12 |
httpx
|
13 |
+
|
14 |
+
django-environ
|
15 |
+
supabase
|
scripts/make_request.py
CHANGED
@@ -12,3 +12,69 @@ request = requests.post(url=
|
|
12 |
).json()
|
13 |
|
14 |
print(request)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
).json()
|
13 |
|
14 |
print(request)
|
15 |
+
|
16 |
+
|
17 |
+
json = {
|
18 |
+
'message': {
|
19 |
+
'_vnd': {
|
20 |
+
'v1': {
|
21 |
+
'author': {
|
22 |
+
'id': 57787919091,
|
23 |
+
'name': 'GT',
|
24 |
+
'type': 'OWNER'
|
25 |
+
},
|
26 |
+
'card_uuid': None,
|
27 |
+
'chat': {
|
28 |
+
'assigned_to': {
|
29 |
+
'id': 'jhk151kl-hj42-3752-3hjk-h4jk6hjkk2',
|
30 |
+
'name': 'Greg Thompson',
|
31 |
+
'type': 'OPERATOR'
|
32 |
+
},
|
33 |
+
'contact_uuid': 'j43hk26-2hjl-43jk-hnk2-k4ljl46j0ds09',
|
34 |
+
'inserted_at': '2022-07-05T04:00:34.033522Z',
|
35 |
+
'owner': '+57787919091',
|
36 |
+
'permalink': 'https://app.turn.io/c/4kl209sd0-a7b8-2hj3-8563-3hu4a89b32',
|
37 |
+
'state': 'OPEN',
|
38 |
+
'state_reason': 'Re-opened by inbound message.',
|
39 |
+
'unread_count': 19,
|
40 |
+
'updated_at': '2023-01-10T02:37:28.487319Z',
|
41 |
+
'uuid': '4kl209sd0-a7b8-2hj3-8563-3hu4a89b32'
|
42 |
+
},
|
43 |
+
'direction': 'inbound',
|
44 |
+
'faq_uuid': None,
|
45 |
+
'in_reply_to': None,
|
46 |
+
'inserted_at': '2023-01-10T02:37:28.477940Z',
|
47 |
+
'labels': [{
|
48 |
+
'confidence': 0.506479332,
|
49 |
+
'metadata': {
|
50 |
+
'nlu': {
|
51 |
+
'confidence': 0.506479332,
|
52 |
+
'intent': 'question',
|
53 |
+
'model_name': 'nlu-general-spacy-ngrams-20191014'
|
54 |
+
}
|
55 |
+
},
|
56 |
+
'uuid': 'ha7890s2k-hjk2-2476-s8d9-fh9779a8a9ds',
|
57 |
+
'value': 'Unclassified'
|
58 |
+
}],
|
59 |
+
'last_status': None,
|
60 |
+
'last_status_timestamp': None,
|
61 |
+
'on_fallback_channel': False,
|
62 |
+
'rendered_content': None,
|
63 |
+
'uuid': 's8df79zhws-h89s-hj23-7s8d-thb248d9bh2qn'
|
64 |
+
}
|
65 |
+
},
|
66 |
+
'from': 57787919091,
|
67 |
+
'id': 'hsjkthzZGehkzs09sijWA3',
|
68 |
+
'text': {'body': 'eight'},
|
69 |
+
'timestamp': 1673318248,
|
70 |
+
'type': 'text'
|
71 |
+
},
|
72 |
+
'type': 'message'
|
73 |
+
}
|
74 |
+
|
75 |
+
request = requests.post(url=
|
76 |
+
'http://localhost:7860/nlu',
|
77 |
+
json=json
|
78 |
+
).json()
|
79 |
+
|
80 |
+
print(request)
|