Как добиться многопользовательского параллелизма в чате python? - PullRequest
0 голосов
/ 04 февраля 2019

Я создаю python-чатбота с помощью мессенджера Facebook.

Если один пользователь использует мой чат-бот, он будет работать правильно, но если несколько пользователей одновременно используют чат-бота (одновременно), ответы пользователей сталкиваются друг с другом и заканчиваются ошибкой.

Мой код работает с одиночными пользователями, обращающимися к чат-боту, но он потерпит неудачу, если пользователи одновременно обращаются к чат-боту (как будто он не обрабатывает многопроцессорный или многопоточный сценарий) Так как я не знаю об этих концепциях в python, трудно идти вперед, поэтому я застрял в этом 3 дня.

Пожалуйста, помогите мне преодолеть мою проблему.

Ниже приведен мой код для справки:

    symptoms = []    
    conditions = ''
    q_number = 0
    state = 4
    prev = ''
    age = 0
    sex = ''
    count_age= 0
    count_gender = 0
    count_boolean = 0
    infermedica_question = ''
    #Core function of the calladoc
    @app.route('/')    
    def get_question(sender_id,user_input,first_name):

        global symptoms
        global conditions
        global q_number
        global state
        global prev 
        global age 
        global sex
        global raw_symptoms
        global count_age
        global count_gender
        global infermedica_question

        user_input = user_input.lower()
        #user to end the conversation with bot
        try: 
            if (user_input == '###' or user_input == 'thanks'or user_input == 'quit'or user_input == 'exit'):
                state = 4
                q_number = 0
                symptoms = []
                conditions = ''
                count_age = 0
                count_gender = 0
                return "No problem, incase if you would like to start over again, type Hi. Thank you for visiting us!"

            #If user requires more information about the diagnosis.
            elif (user_input == 'more info' or user_input =='more information'):
                length = len(conditions)
                probability0 = conditions[0]['probability'] * 100
                info0 = api.condition_details(conditions[0]['id'])
                severity0 = get_severity(info0.severity)
                #treatment = webscraper.parse_result(conditions[0]['name'])
                text = "You are most likely suffering from " + conditions[0]['name'] + " with %0.f%% probability. " % probability0 + severity0 + info0.extras['hint'] + '\n' 
                if(length >=2):
                    probability1 = conditions[1]['probability'] * 100
                    info1 = api.condition_details(conditions[1]['id'])
                    severity1 = get_severity(info1.severity)
                    text += "\nYour second most likely suffering from " + conditions[1]['name'] + " with %0.f%% probability. " % probability1 + severity1 + info1.extras['hint'] + '\n'
                if (length > 2):
                    probability2 = conditions[2]['probability'] * 100
                    info2 = api.condition_details(conditions[2]['id'])
                    severity2 = get_severity(info2.severity)
                    text += " \nYour third most likely suffering from " + conditions[2]['name'] + " with %0.f%% probability. " % probability2 + severity2 + info2.extras['hint'] + '\n'
                return text +"\n \n Please note that this diagnosis is provided solely for informational purposes and is not a qualified medical opinion. In case of health emergency, call your local emergency number immediately. Thank you! \n\n If you would like to start over again, say 'Hi'."

            #Initiate the conversation with the bot
            elif (user_input =='hi' or user_input =='restart' or user_input =='hello' or user_input == 'get started' or user_input == 'user_defined_payload' or user_input == '#R#'):
                count_age = 0
                count_gender = 0
                state=3
                return "Hi "+first_name+ "! My name is Lisa and I am a *digital healthcare assistant* , here to help diagnose your health problem.\n\nAnytime during our conversation,you may enter '###' to leave.\n\nCould you start with sharing your age please(Ex:- 28)"
            #collect the age from user and age should be in number format
            try:
                if (state == 3):
                    print("inside age")
                    user_input= user_input
                    print(user_input)

                    if int(user_input) in range(1, 110):
                        state=2
                        user_input = user_input
                        age=user_input
                        print(age)
                        return send_button_gender(sender_id)
                    elif int(user_input)>110:
                        if(count_age!=2):
                            count_age += 1
                            state=3
                            return "Please enter an appropriate age."
                        elif(count_age==2):
                            return "Please revisit us!"  
            except:
                if(count_age!=2):
                    count_age += 1
                    state=3
                    return "Sorry, Please share your age(Ex:- 28)."
                elif(count_age==2):
                    return "Please revisit us!"
            #collect the gender information from use
            if (state ==2):
                if(user_input=='male' or user_input=='female' or user_input=='m' or user_input =='f'):
                    state=1
                    sex = user_input
                    print(sex)
                    return "Please share your Symptoms (separated by comma)."
                elif(user_input!='male' or user_input!='female'):
                    if(count_gender!=2):
                        count_gender += 1
                        print(count_gender)
                        state=2
                        return send_button_gender(sender_id)
                    elif(count_gender==2):
                        return "Please revisit us!"    

             #Parse symptoms and collect age, gender 
            if (state == 1):
                print("entered inside the state 1")
                try:
                    if(user_input == str(user_input)):
                        print("entered string")
                        #parse the raw symptoms to required format
                        resp = api.parse(user_input)
                        profile = infermedica_api.Diagnosis(sex=sex, age=age)
                        # only single questions
                        profile.extras['ignore_groups']=True 
                        for item in resp.mentions:
                            symptoms.append([item.id, item.choice_id])
                            profile.add_symptom(item.id, item.choice_id)
                            if (len(symptoms) == 0):
                                return "Sorry, I did not understand. Please enter more specific symptoms (separated by comma)."
                            print(profile)
                        #uses the diagnosis endpoint for intial diagnose    
                        profile = api.diagnosis(profile)
                        state = 0
                        symptoms = symptoms
                        prev = profile.question.items[0]['id']
                        conditions = profile.conditions
                        #Added yes/no/not sure button 
                        infermedica_question = profile.question.text
                        print(infermedica_question)
                        if(len(profile.question.text) > 0):
                            #Added yes/no/not sure button 
                            log("sending message to {recipient}: {text}".format(recipient=sender_id, text="button"))
                            params = {
                                "access_token": ACCESS_TOKEN
                            }
                            headers = {
                                "Content-Type": "application/json"
                            }    
                            data = json.dumps({
                                    'recipient': {
                                        'id': sender_id
                                    },

                                  "message":{
                                    "text": infermedica_question,
                                    "quick_replies":[
                                      {
                                        "content_type":"text",
                                        "title":"Yes",
                                        "payload":"yes",
                                   "image_url":"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRU6MCNSRzaqNaNTWTW77xHKOZ-kq38u5sIlKUIil9Bm1uwfwh4xg"
                                      },
                                      {
                                        "content_type":"text",
                                        "title":"No",
                                        "payload":"no",
                                   "image_url":"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQq3Povw8Bf9U9OmkNhDefq9cN0qyidMrqbTcgQrPyugLr9K8uNSQ"
                                      },
                                  {
                                        "content_type":"text",
                                        "title":"Not Sure",
                                        "payload":"not sure",
                                   "image_url":"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRPCP-VoFrfYvX_BDSi_yOqcBiZCu_FtOQTGUwHoFAnWHCRUV4q"
                                      }
                                    ]
                              }
                            })  
                            r = requests.post("https://graph.facebook.com/v3.1/me/messages", params=params, headers=headers, data=data)
                            if r.status_code != 200:
                                log(r.status_code)
                                log(r.text)
                            log(r.text)
                except:
                    return "Sorry! service is temporarily down today. Please try again in sometime."
            else:
                #Checks whether the diagnose report has reached 90% probability or not
                if (conditions[0]['probability'] < .9):
                    def send_quickreplies_boolean(sender_id):
                        log("sending message to {recipient}: {text}".format(recipient=sender_id, text="button"))

                        params = {
                            "access_token": ACCESS_TOKEN
                        }
                        headers = {
                            "Content-Type": "application/json"
                        }    
                        data = json.dumps({
                                'recipient': {
                                    'id': sender_id
                                },

                              "message":{
                                "text": infermedica_question,
                                "quick_replies":[
                                              {
                                                "content_type":"text",
                                                "title":"Yes",
                                                "payload":"yes",
                                            "image_url":"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRU6MCNSRzaqNaNTWTW77xHKOZ-kq38u5sIlKUIil9Bm1uwfwh4xg"
                                              },
                                              {
                                                "content_type":"text",
                                                "title":"No",
                                                "payload":"no",
                                            "image_url":"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQq3Povw8Bf9U9OmkNhDefq9cN0qyidMrqbTcgQrPyugLr9K8uNSQ"

                                              },
                                          {
                                                "content_type":"text",
                                                "title":"Not Sure",
                                                "payload":"not sure",
                                            "image_url":"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRPCP-VoFrfYvX_BDSi_yOqcBiZCu_FtOQTGUwHoFAnWHCRUV4q"
                                              }
                                        ]
                          }
                        })  
                        r = requests.post("https://graph.facebook.com/v3.1/me/messages", params=params, headers=headers, data=data)
                        if r.status_code != 200:
                            log(r.status_code)
                            log(r.text)
                        log(r.text)

                    user_input = user_input.lower()
                    if (user_input == 'y' or user_input == 'yes'):
                        index = 'present'
                    elif (user_input == 'n' or user_input == 'no'):
                        index = 'absent'
                    elif (user_input == 'dont know' or user_input == 'not sure' or user_input== "don't know"):
                        index ='unknown'
                    else:
                        return send_quickreplies_boolean(sender_id)
                    #Repeat asking the questions until it reaches 90%    
                    profile = infermedica_api.Diagnosis(sex=sex, age=age)
                    profile.extras['ignore_groups']=True
                    for i in range (len(symptoms)):
                        profile.add_symptom(symptoms[i][0], symptoms[i][1])
                    profile.add_symptom(prev, index)
                    profile = api.diagnosis(profile)
                    q_number = q_number + 1
                    symptoms.append([prev, index])
                    symptoms = symptoms
                    prev = profile.question.items[0]['id']
                    conditions = profile.conditions             
                    #check the condition whether Q/A's has reached of 10 questions or not
                    if (q_number <= 10):
                        infermedica_question = profile.question.text
                        #Added yes/no/not sure button 
                        log("sending message to {recipient}: {text}".format(recipient=sender_id, text="button"))

                        params = {
                                "access_token": ACCESS_TOKEN
                            }
                        headers = {
                                "Content-Type": "application/json"
                            }    
                        data = json.dumps({
                                    'recipient': {
                                        'id': sender_id
                                    },

                                  "message":{
                            "text": infermedica_question,
                            "quick_replies":[
                              {
                                "content_type":"text",
                                "title":"Yes",
                                "payload":"yes",
                            "image_url":"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRU6MCNSRzaqNaNTWTW77xHKOZ-kq38u5sIlKUIil9Bm1uwfwh4xg"
                              },
                              {
                                "content_type":"text",
                                "title":"No",
                                "payload":"no",
                            "image_url":"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQq3Povw8Bf9U9OmkNhDefq9cN0qyidMrqbTcgQrPyugLr9K8uNSQ"

                              },
                          {
                                "content_type":"text",
                                "title":"Not Sure",
                                "payload":"not sure",
                            "image_url":"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRPCP-VoFrfYvX_BDSi_yOqcBiZCu_FtOQTGUwHoFAnWHCRUV4q"
                              }
                            ]
                              }
                            })  
                        r = requests.post("https://graph.facebook.com/v3.1/me/messages", params=params, headers=headers, data=data)
                        if r.status_code != 200:
                            log(r.status_code)
                            log(r.text)
                        log(r.text)   
                    else:
                        #probability = conditions[0]['probability'] * 100
                        length = len(conditions)
                        text = "You are most likely suffering from" + conditions[0]['name']
                        if (length > 1):
                            text += ", " + conditions[1]['name']
                        if (length > 2):
                            text += ", " + conditions[2]['name']
                            text += "For more information, type 'more info'.To continue answer the following questions: " + profile.question.text
                        return text
                else:
                    state = 4
                    q_number = 0    
                    count_age =0
                    count_gender =0
                    symptoms =[]        
                    length = len(conditions)
                    probability0 = conditions[0]['probability'] * 100
                    info0 = api.condition_details(conditions[0]['id'])
                    severity0 = get_severity(info0.severity)
                    text = "You are most likely suffering from " + conditions[0]['name'] + " with %.0f%% probability. " % probability0 + severity0 + info0.extras['hint'] + '\n' 
                    if (length > 1):
                        probability1 = conditions[1]['probability'] * 100
                        info1 = api.condition_details(conditions[1]['id'])
                        severity1 = get_severity(info1.severity)
                        text += "\nYour second most likely suffering from " + conditions[1]['name'] + " with %.0f%% probability. " % probability1 + severity1 + info1.extras['hint'] + '\n' 
                    if (length > 2):
                        probability2 = conditions[2]['probability'] * 100
                        info2 = api.condition_details(conditions[2]['id'])
                        severity2 = get_severity(info2.severity)
                        text += "\nYour third most likely diagnosis is " + conditions[2]['name'] + " with a %.0f%% probability. " % probability2 + severity2 + info2.extras['hint'] + '\n'
                    conditions = ''
                    return text +"\n Please note that this diagnosis is provided solely for informational purposes and is not a qualified medical opinion. In case of health emergency, call your local emergency number immediately. Thank you! \n\nIncase if you would like to start over again, say 'Hi'.\n\nWould appreciate if you could spend a little while sharing feedback on us, through the Reviews option on our Facebook page."

        except Exception as e:
            print("Error has occurred", e)
            return "Sorry, looks like you have entered an incorrect input. We would need to restart our conversation. Say 'Hi' to do so."      
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...