Continuo meus estudos com Flask, para brincar um pouco com o que estou aprendendo resolvi fazer um chatbot utilizando a biblioteca PyAIML e os arquivos AIML da A.L.I.C.E. AI Foundation.
Pra quem não sabe, os arquivos AIML (Artificial Intelligence Markup Language) são marcações baseadas em XML para inteligência artificial. Usando a biblioteca PyAIML fica muito simples fazer um chatbot em Python. Mas eu queria fazê-lo via web e foi aí que o Flask entrou.
Utilizei o Flask apenas para lidar com os requests e responses via web. Ou seja, ele recebe uma pergunta vinda do navegador e devolve uma resposta do bot.
Para ver o código-fonte completo do meu chatbot, acesse meu github.
Vendo o código-fonte, percebe-se que na raiz temos apenas o diretório app e o lib, além do arquivo run.py, que roda o servidor. Dentro do diretório app temos os arquivos do Flask: __init__.py e o views.py. No diretório lib está a biblioteca PyAIML e os arquivos AIML, importados da A.L.I.C.E. AI Foundation. Nestes arquivos eu fiz pouquíssimas alterações para o funcionamento básico do Jarvis, nome que dei ao meu chatbot.
Dentro do arquivo app/__init__.py eu importo o Flask e biblioteca PyAIML, para poder utilizá-la no arquivo app/views.py. Perceba que também importo o arquivo brain.brn, que é a “compilação” dos arquivos AIML, ou seja, é o cérebro do bot. Se ele não existir, o Kernel da biblioteca PyAIML vai criá-lo. Exemplo nas linhas abaixo, retiradas do arquivo app/__init__.py.
brainfile = os.path.join('lib', 'pyaiml', 'brain.brn') aimlfiles = os.path.join('lib', 'pyaiml', 'aiml', 'std-startup.aiml') k = aiml.Kernel() if os.path.isfile(brainfile): k.bootstrap(brainFile = brainfile) else: k.bootstrap(learnFiles = aimlfiles, commands = 'load aiml b') k.saveBrain(brainfile)
Uma pequena observação, estou importando os arquivos com os.path.join() para que não precise me preocupar se estou em sistema operacional Windows ou em Unix-based. Isso foi necessário porque no Windows as barras que separam os arquivos são inversas às dos sistemas baseados em Unix (como Linux e MacOS).
No arquivo app/views.py encontramos as definições de rotas (@app.route()) e definimos o que cada endereço web vai fazer no sistema. No caso, temos o / ou /index, que apenas mostra o template básico, através do método render_template do Flask, e temos o /talk, que recebe a “pergunta” do browser e envia a resposta transformada em um objeto JSON com o método jsonify do Flask. Os outros métodos são apenas handlers para os erros 404 (página não encontrada) e 500 (erro interno do servidor). Veja o index e o talk no exemplo abaixo, retirado do arquivo app/views.py.
@app.route('/', methods=['GET']) @app.route('/index', methods=['GET']) def index(): return render_template('index.html') @app.route('/talk', methods=['GET']) def talk(): question = request.args.get('question') answer = k.respond(question) return jsonify(question=question, answer=answer)
Lembrando que quando chamamos k.respond() no método talk() estamos chamando a biblioteca PyAIML para fazer o trabalho pesado por nós. Já a importamos no arquivo app/__init__.py e a passamos para a variável app.
É importante lembrar que aquilo que fomos utilizar em um programa Python tem que ser importado. Por isso é comum vermos os comandos import no começo dos arquivos. Por exemplo, no arquivo app/views.py eu importei o render_template, o request e o jsonify do Flask e o app e k (que contem a biblioteca PyAIML) do nosso app iniciado no arquivo app/__init__.py.
from flask import render_template, request, jsonify from app import app, k
Com a biblioteca PyAIML fazendo a interpretação dos arquivos AIML, o Flask tinha pouquíssimo trabalho pela frente. Com apenas alguns poucos métodos escritos eu consegui rodar o aplicativo web. Isto é algo que tem me agradado muito no Python e no Flask.
Utilizar o PyAIML também foi simples, mas para entender como personalizar o bot (mudar o nome, nascimento, preferências, etc) eu levei um tempinho. Precisava entender que os “predicates” do bot precisavam ser mudados no arquivo lib/pyaiml/aiml/Kernel.py da biblioteca. Para facilitar, criei um arquivo chamado lib/pyaiml/aiml/BotPredicates.py e o importei no Kernel.py, como mostro abaixo.
import BotPredicates
# Set up the bot predicates self._botPredicates = BotPredicates.bot
Acabou sendo mais simples do que eu imaginava criar o Jarvis. Agora vou continuar brincando um pouco com ele. Quero adicionar reconhecimento de voz para que o usuário possa conversar com o Jarvis. Também quero que o usuário se registre com login e senha, para que o Jarvis já conheça seus amigos quando eles vierem conversar. A medida que eu for desenvolvendo essas novas funcionalidades vou postando algumas notas por aqui.