CoolFace
Apppublic

Hobson/mathtext-fastapi

sourceHugging Faceagpl-3.0updated 3y agoView on Hugging Face
1likes
app.py295 linesDownload Raw Back to root
1"""FastAPI endpoint2To run locally use 'uvicorn app:app --host localhost --port 7860'3"""4import ast5import scripts.quiz.generators as generators6import scripts.quiz.hints as hints7import scripts.quiz.questions as questions8import scripts.quiz.utils as utils9import sentry_sdk10 11from fastapi import FastAPI, Request12from fastapi.responses import JSONResponse13from fastapi.staticfiles import StaticFiles14from fastapi.templating import Jinja2Templates15from mathtext.sentiment import sentiment16from mathtext.text2int import text2int17from pydantic import BaseModel18 19from mathtext_fastapi.logging import prepare_message_data_for_logging20from mathtext_fastapi.conversation_manager import manage_conversation_response21from mathtext_fastapi.nlu import evaluate_message_with_nlu22from mathtext_fastapi.nlu import run_intent_classification23 24sentry_sdk.init(25    dsn="https://143c9ac3f429452eb036deda0e4d5aef@o1297809.ingest.sentry.io/4504896688881664",26 27    # Set traces_sample_rate to 1.0 to capture 100%28    # of transactions for performance monitoring.29    # We recommend adjusting this value in production,30    traces_sample_rate=0.20,31)32 33app = FastAPI()34 35app.mount("/static", StaticFiles(directory="static"), name="static")36 37templates = Jinja2Templates(directory="templates")38 39 40class Text(BaseModel):41    content: str = ""42 43 44@app.get("/")45def home(request: Request):46    return templates.TemplateResponse("home.html", {"request": request})47 48 49@app.get("/sentry-debug")50async def trigger_error():51    division_by_zero = 1 / 052 53 54@app.post("/hello")55def hello(content: Text = None):56    content = {"message": f"Hello {content.content}!"}57    return JSONResponse(content=content)58 59 60@app.post("/sentiment-analysis")61def sentiment_analysis_ep(content: Text = None):62    ml_response = sentiment(content.content)63    content = {"message": ml_response}64    return JSONResponse(content=content)65 66 67@app.post("/text2int")68def text2int_ep(content: Text = None):69    ml_response = text2int(content.content)70    content = {"message": ml_response}71    return JSONResponse(content=content)72 73 74@app.post("/manager")75async def programmatic_message_manager(request: Request):76    """77    Calls conversation management function to determine the next state78 79    Input80    request.body: dict - message data for the most recent user response81    {82        "author_id": "+47897891",83        "contact_uuid": "j43hk26-2hjl-43jk-hnk2-k4ljl46j0ds09",84        "author_type": "OWNER",85        "message_body": "a test message",86        "message_direction": "inbound",87        "message_id": "ABJAK64jlk3-agjkl2QHFAFH",88        "message_inserted_at": "2022-07-05T04:00:34.03352Z",89        "message_updated_at": "2023-02-14T03:54:19.342950Z",90    }91 92    Output93    context: dict - the information for the current state94    {95        "user": "47897891",96        "state": "welcome-message-state",97        "bot_message": "Welcome to Rori!",98        "user_message": "",99        "type": "ask"100    }101    """102    data_dict = await request.json()103    context = manage_conversation_response(data_dict)104    return JSONResponse(context)105 106 107@app.post("/intent-classification")108def intent_classification_ep(content: Text = None):109    ml_response = run_intent_classification(content.content)110    content = {"message": ml_response}111    return JSONResponse(content=content)112 113 114@app.post("/nlu")115async def evaluate_user_message_with_nlu_api(request: Request):116    """ Calls nlu evaluation and returns the nlu_response117 118    Input119    - request.body: json - message data for the most recent user response120 121    Output122    - int_data_dict or sent_data_dict: dict - the type of NLU run and result123      {'type':'integer', 'data': '8', 'confidence': 0}124      {'type':'sentiment', 'data': 'negative', 'confidence': 0.99}125    """126    data_dict = await request.json()127    message_data = data_dict.get('message_data', '')128    nlu_response = evaluate_message_with_nlu(message_data)129    return JSONResponse(content=nlu_response)130    131 132@app.post("/question")133async def ask_math_question(request: Request):134    """Generate a question and return it as response along with question data135    136    Input137    request.body: json - amount of correct and incorrect answers in the account138    {139        'number_correct': 0,140        'number_incorrect': 0,141        'level': 'easy'142    }143 144    Output145    context: dict - the information for the current state146    {147        'text': 'What is 1+2?',148        'question_numbers': [1,2,3], #3 numbers - current number, ordinal number, times149        'right_answer': 3,150        'number_correct': 0,151        'number_incorrect': 0,152        'hints_used': 0153    }154    """155    data_dict = await request.json()156    message_data = ast.literal_eval(data_dict.get('message_data', '').get('message_body', ''))157    right_answers = message_data['number_correct']158    wrong_answers = message_data['number_incorrect']159    level = message_data['level']160 161    return JSONResponse(generators.start_interactive_math(right_answers, wrong_answers, level))162 163 164@app.post("/hint")165async def get_hint(request: Request):166    """Generate a hint and return it as response along with hint data167    168    Input169    request.body:170    {171        'question_numbers': [1,2,3], #3 numbers - current number, ordinal number, times172        'right_answer': 3,173        'number_correct': 0,174        'number_incorrect': 0,175        'level': 'easy',176        'hints_used': 0177    }178 179    Output180    context: dict - the information for the current state181    {182        'text': 'What is 1+2?',183        'question_numbers': [1,2,3], #2 or 3 numbers184        'right_answer': 3,185        'number_correct': 0,186        'number_incorrect': 0,187        'level': 'easy',188        'hints_used': 0189    }190    """191    data_dict = await request.json()192    message_data = ast.literal_eval(data_dict.get('message_data', '').get('message_body', ''))193    question_numbers = message_data['question_numbers']194    right_answer = message_data['right_answer']195    number_correct = message_data['number_correct']196    number_incorrect = message_data['number_incorrect']197    level = message_data['level']198    hints_used = message_data['hints_used']199 200    return JSONResponse(hints.generate_hint(question_numbers, right_answer, number_correct, number_incorrect, level, hints_used))201 202 203@app.post("/generate_question")204async def generate_question(request: Request):205    """Generate a bare question and return it as response206    207    Input208    request.body: json - level209    {210        'level': 'easy'211    }212 213    Output214    context: dict - the information for the current state215    {216        "question": "Let's count up by 2s. What number is next if we start from 10?217        6 8 10 ..."218    }219    """220    data_dict = await request.json()221    message_data = ast.literal_eval(data_dict.get('message_data', '').get('message_body', ''))222    level = message_data['level']223 224    return JSONResponse(questions.generate_question_data(level)['question'])225 226 227@app.post("/numbers_by_level")228async def get_numbers_by_level(request: Request):229    """Generate three numbers and return them as response230    231    Input232    request.body: json - level233    {234        'level': 'easy'235    }236 237    Output238    context: dict - three generated numbers for specified level239    {240        "current_number": 10,241        "ordinal_number": 2,242        "times": 1243    }244    """245    data_dict = await request.json()246    message_data = ast.literal_eval(data_dict.get('message_data', '').get('message_body', ''))247    level = message_data['level']248    return JSONResponse(questions.generate_numbers_by_level(level))249 250 251@app.post("/number_sequence")252async def get_number_sequence(request: Request):253    """Generate a number sequence254    255    Input256    request.body: json - level257    {258        "current_number": 10,259        "ordinal_number": 2,260        "times": 1261    }262 263    Output264    one of following strings with (numbers differ):265    ... 1 2 3266    1 2 3 ...267    """268    data_dict = await request.json()269    message_data = ast.literal_eval(data_dict.get('message_data', '').get('message_body', ''))270    cur_num = message_data['current_number']271    ord_num = message_data['ordinal_number']272    times = message_data['times']273    return JSONResponse(questions.generate_number_sequence(cur_num, ord_num, times))274 275 276@app.post("/level")277async def get_next_level(request: Request):278    """Depending on current level and desire to level up/down return next level279    280    Input281    request.body: json - level282    {283        "current_level": "easy",284        "level_up": True285    }286 287    Output288    Literal - "easy", "medium" or "hard"289    """290    data_dict = await request.json()291    message_data = ast.literal_eval(data_dict.get('message_data', '').get('message_body', ''))292    cur_level = message_data['current_level']293    level_up = message_data['level_up']294    return JSONResponse(utils.get_next_level(cur_level, level_up))295