gunthercox / ChatterBot

ChatterBot is a machine learning, conversational dialog engine for creating chat bots
https://chatterbot.readthedocs.io
BSD 3-Clause "New" or "Revised" License
14.08k stars 4.44k forks source link

deploy on Heroku #1030

Closed AdriG83 closed 6 years ago

AdriG83 commented 7 years ago

Hi, I created my first Telegram chatbot and I deployed it on Heroku.

It doesn't work. My program has these files:

Procfile
requirements.txt
Magghy.py
magghybot.py
nltk.txt
runtime.txt
telegramtoken.txt
botusers.csv
conversations.yml (in folder named lang)
math_words.json (in folder named lang)

The logs are:

State changed from crashed to starting
Starting process with command `python magghybot.py`
State changed from starting to up
State changed from up to crashed
Process exited with status 0
State changed from crashed to down
Starting process with command `python magghybot.py`
State changed from starting to up
State changed from up to crashed
State changed from crashed to starting
Process exited with status 0
...

In Procfile I wrote:

worker: python magghybot.py

In magghybot.py file the code is:

import os
import os.path
import sys
from inspect import getsourcefile
from os.path import abspath
from chatterbot import ChatBot

class MagghyBot(object):

    def __init__(self, lang = "english"):
        self.language = lang
        self.chatbot = ChatBot(
            'MagghyBot',
            logic_adapters=[
            "chatterbot.logic.MathematicalEvaluation",
            "chatterbot.logic.TimeLogicAdapter",
            "chatterbot.logic.BestMatch"
            ],
            #input_adapter="chatterbot.input.VariableInputTypeAdapter",
            #output_adapter="chatterbot.output.OutputAdapter"
            trainer='chatterbot.trainers.ChatterBotCorpusTrainer'
        ) 
        self.instdir = "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/chatterbot_corpus/data" + self.language + "/"
        self.localdir = os.path.abspath(os.path.dirname(sys.argv[0])) + "/lang/" + self.language + "/chatcorpus/"

    def train(self):
        if self.checkdirnotempty(self.localdir):
            print(self.localdir)
            self.chatbot.train(
                self.localdir
            )
        elif self.checkdirnotempty(self.instdir):
            print(self.instdir)
            self.chatbot.train(
                self.instdir
            )
        else:
            print("Using standard english corpus")
            self.chatbot.train("chatterbot.corpus.english.greetings")

    def reply(self, phrase = ""):
        # Get a response to an input statement
        response = self.chatbot.get_response(phrase)
        return response

    def checkdirnotempty(self, folder = ""):
        check = False
        if os.path.isdir(folder):
            entities = os.listdir(folder)
            for entity in entities:
                if os.path.isfile(folder + entity):
                    check = True
                    break
        return check`

In Magghy.py, I wrote:

import time
import random
import datetime
import telepot
import os
import sys
import subprocess
from magghybot import MagghyBot

telegramtoken = '' #telegram bot token from BotFather
checkuserid = 394287240 #enable users whitelist, so only certain people can talk with this bot
usersfile = 'botusers' #the file where we store the list of users who can talk with bot
attemptsfile = '/tmp/attempts.log' #the file where we log denied accesses
active = 1 #if set to 0 the bot will stop

language = "italiano"

chatter = MagghyBot(language)
chatter.train()

if telegramtoken == '' and os.path.isfile("telegramtoken.txt"):
    text_file = open("telegramtoken.txt", "r")
    telegramtoken = text_file.read().replace("\n", "")
    text_file.close()

print("Connecting to Telegram...")
bot = telepot.Bot(telegramtoken)
print(bot.getMe())

def listusers():
    if not os.path.isfile(usersfile):
        return ''
    text_file = open(usersfile, "r")
    lines = text_file.read().split(',')
    text_file.close()
    del lines[-1] #remove last element since it is blank
    return lines

def adduser(name):
    csv = ""
    users = listusers()
    if users != "":
        for usr in users:
            csv = csv+usr+","
    csv = csv+name+","
    text_file = open(usersfile, "w")
    text_file.write(csv)
    text_file.close()

def deluser(name):
    csv = ""
    users = listusers()
    if users != "":
        for usr in users:
            if usr != name:
                csv = csv+usr+","
    text_file = open(usersfile, "w")
    text_file.write(csv)
    text_file.close()

def handle(msg):
    global bot
    global chatter
    global language

    chat_id = msg['chat']['id']
    sender = msg['from']['id']

    users = listusers()

    if checkuserid == 1:
        verified = 0
        if users != "":
            for usr in users:
                if str(sender) == usr:
                    verified = 1
        if verified == 0:
            bot.sendMessage(chat_id, "I don't talk with strangers, dear "+str(sender))
            #write this user in the list of attempted accesses
            if attemptsfile != '':
                lines = ''
                if os.path.isfile(attemptsfile):
                    text_file = open(attemptsfile, "r")
                    lines = text_file.read()
                    text_file.close()
                lines = lines + str(datetime.datetime.now()) + " --- UserdID: " + str(sender) + " DENIED \n"
                text_file = open(attemptsfile, "w")
                text_file.write(lines)
                text_file.close()
            return

    command = ''

    try:
        if msg['text'] != '':
            command = msg['text']
            print('Got command: ' + command)
    except:
        print("No text in this message")

    if command == '/time':
        bot.sendMessage(chat_id, str(datetime.datetime.now()))
    elif '/adduser' in command:
        if len(command.split(' ')) > 1:
            usrname = command.split(' ')[1]
            adduser(usrname)
            bot.sendMessage(chat_id, "User "+usrname+" added")
    elif '/deluser' in command:
        if len(command.split(' ')) > 1:
            usrname = command.split(' ')[1]
            deluser(usrname)
            bot.sendMessage(chat_id, "User "+usrname+" deleted")
    elif command == '/help':
        bot.sendMessage(chat_id, "/adduser /deluser /time /exit")
    elif command == '/exit':
        global active
        active = False
        bot.sendMessage(chat_id, "The bot will shutdown in 10 seconds")
    elif command != '':
        answer = chatter.reply(command)
        bot.sendMessage(chat_id, str(answer))

bot.message_loop(handle)
print('I am listening ...')

while active:
    time.sleep(10)
print("Exiting")
sys.exit()`

What is the problem? Please help me!

Thanks a lot!

Adri

vkosuri commented 7 years ago

@adryr83 It is very difficulty to me find root cause of the above code,

Couple of questions Did your bot working on locally? Do you have heroku logs?

And also see error code of heroku https://devcenter.heroku.com/articles/error-codes, to familiar what exactly is happening

A chatterbot heoku example located here https://github.com/vkosuri/chatterbot-live-example

AdriG83 commented 7 years ago

Hi @vkosuri, my bot works perfectly on locally. I have this Heroku logs:

2017-10-19T08:16:11.000000+00:00 app[api]: Build succeeded 2017-10-19T08:16:44.658372+00:00 heroku[worker.1]: State changed from crashed to starting 2017-10-19T08:16:50.967642+00:00 heroku[worker.1]: Starting process with commandpython Magghy.py 2017-10-19T08:16:51.590782+00:00 heroku[worker.1]: State changed from starting to up 2017-10-19T08:16:54.673293+00:00 heroku[worker.1]: State changed from up to crashed 2017-10-19T08:16:54.665246+00:00 heroku[worker.1]: Process exited with status 1 2017-10-19T08:16:54.331086+00:00 app[worker.1]: /app/lang/italiano/chatcorpus/ conversations.yml Training: [# ] 4%Traceback (most recent call last): 2017-10-19T08:16:54.529802+00:00 app[worker.1]: File "Magghy.py", line 27, in <module> 2017-10-19T08:16:54.529918+00:00 app[worker.1]: chatter.train() 2017-10-19T08:16:54.530022+00:00 app[worker.1]: self.localdir 2017-10-19T08:16:54.530029+00:00 app[worker.1]: File "/app/.heroku/python/lib/python3.6/site-packages/chatterbot/trainers.py", line 137, in train 2017-10-19T08:16:54.530155+00:00 app[worker.1]: Response(previous_statement_text) 2017-10-19T08:16:54.530159+00:00 app[worker.1]: File "/app/.heroku/python/lib/python3.6/site-packages/chatterbot/conversation/response.py", line 8, in __init__ 2017-10-19T08:16:54.529922+00:00 app[worker.1]: File "/app/magghybot.py", line 37, in train 2017-10-19T08:16:54.530238+00:00 app[worker.1]: import dateutil.parser as date_parser 2017-10-19T08:16:54.530252+00:00 app[worker.1]: File "/app/.heroku/python/lib/python3.6/site-packages/dateutil/parser.py", line 158 2017-10-19T08:16:54.530254+00:00 app[worker.1]: l.append("%s=%s" % (attr,value)) 2017-10-19T08:16:54.530274+00:00 app[worker.1]: ^ 2017-10-19T08:16:54.530277+00:00 app[worker.1]: SyntaxError: invalid syntax

I think the problem caused by the two lines (29 and 30) of magghybot.py file. I wrote these lines: self.instdir = "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/chatterbot_corpus/data" + self.language + "/" self.localdir = os.path.abspath(os.path.dirname(sys.argv[0])) + "/lang/" + self.language + "/chatcorpus/"

I put the conversations of my bot in specific files and I indicated the location of them in "self.instdir" and in "self.localdir". For deploy, where can I put them? And how can I indicate their path?

Thanks a lot!

taiwotman commented 7 years ago

Configuration on Heroku is not a straight line graph. It took me a while to set it up with adverto.ai vis-a-vis using this wonderful chatterbot API. Unless I can sit with you on this; but for now, let me hint you on the following to avoid a recurrent crash of your program on Heroku (hope it helps).

Create the settings_dev.py separate from the setting_prod.py and switch either one to your settings.py depending on the one you are working on.

2. You may want to consider removing the following during training of the bot and replace after training:

logic_adapters=[
            "chatterbot.logic.MathematicalEvaluation",
            "chatterbot.logic.TimeLogicAdapter",
            "chatterbot.logic.BestMatch"
            ],
lock[bot] commented 5 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.