0

I am building a data product (an NLP chat application) for which I am learning Flask so that the user can have a better UI to interact with my product.

I have written down the following code in Flask to get the user input and stored it in a variable.

main.py

from flask import Flask, render_template, request
app = Flask(__name__)

@app.route('/')
def index():
   return render_template('init.html')

@app.route('/handle_data', methods = ['POST', 'GET'])
def handle_data():
    userQuestion = request.form['userQuestion']
    print(userQuestion)
    return render_template('init.html', userQuestion = userQuestion)

if __name__ == '__main__':
   app.run()

init.html

<!DOCTYPE HTML>
<html>
<body>


<form action="{{ url_for('handle_data') }}" method="post">
    <input type="text" name="userQuestion">
    <input type="submit">
</form>

</body>
</html>

I've handled the form data and stored it in a variable userQuestion. I want to pass this variable to another python script which contains the code of my training model.

doc2vec_main.py

import gensim
import nltk
import numpy
from gensim import models
from gensim import utils
from gensim import corpora
from nltk.stem import PorterStemmer
ps = PorterStemmer()

sentence0 = models.doc2vec.LabeledSentence(words=[u'sampling',u'what',u'is',u'sampling'],tags=["SENT_0"])
sentence1 = models.doc2vec.LabeledSentence(words=[u'sampling',u'tell',u'me',u'about',u'sampling'],tags=["SENT_1"])
sentence2 = models.doc2vec.LabeledSentence(words=[u'elig',u'what',u'is',u'my',u'elig'],tags=["SENT_2"])
sentence3 = models.doc2vec.LabeledSentence(words=[u'eligiblity',u'limit', u'what',u'is',u'my'],tags=["SENT_3"])
sentence4 = models.doc2vec.LabeledSentence(words=[u'eligiblity',u'claim',u'how',u'much',u'can',u'I'],tags=["SENT_4"])
sentence5 = models.doc2vec.LabeledSentence(words=[u'retir',u'eligibility',u'claim',u'i',u'am',u'how',u'much',u'can',u'i'],tags=["SENT_5"])
# ... list of all the training set.

# User inputs a question
document = input("Ask a question:")
tokenized_document = list(gensim.utils.tokenize(document, lowercase = True, deacc = True))
stemmed_document = []
for w in tokenized_document:
    stemmed_document.append(ps.stem(w))

sentence19 = models.doc2vec.LabeledSentence(words= stemmed_document, tags=["SENT_19"])

sentences = [sentence0,sentence1,sentence2,sentence3, sentence4, sentence5,sentence6, sentence7, sentence8, sentence9, sentence10, sentence11, sentence12, sentence13, sentence14, sentence15, sentence16, sentence17, sentence18, sentence19]

model = models.Doc2Vec(size=4, alpha=0.25, min_alpha=.025, min_count=1)
model.build_vocab(sentences)
for epoch in range(30):
    model.train(sentences, total_examples=model.corpus_count, epochs = 
    model.iter)
    model.alpha -= 0.002
    model.min_alpha = model.alpha
model.save("my_model.doc2vec")
model_loaded = models.Doc2Vec.load('my_model.doc2vec')
print (model.docvecs.most_similar(["SENT_19"]))

My problem is I cannot find a way to connect doc2vec_main.py to main.py and pass the value of userQuestion to the document variable in doc2main.py script. That is when a user inputs a question in the form and clicks submit, the value of the form get passed down to document in doc2vec_main.py and the remaining script runs.

I have searched a lot on the internet but it didn't help. Can you suggest me a way to do it? I'm a complete beginner in Flask so forgive me for any mistake.

K. K.
  • 552
  • 1
  • 11
  • 20
  • Possible duplicate of [Importing variables from another file?](https://stackoverflow.com/questions/17255737/importing-variables-from-another-file) – Craicerjack Jun 26 '17 at 10:32
  • So do you wanna do this? python doc2vec_main.py arg1=from_flask ??? – Dimitrios Filippou Jun 26 '17 at 10:36
  • @Craicerjack, Using userQuestion out of the function handle_data() throws an error 'userQuestion not defined'. – K. K. Jun 26 '17 at 10:36
  • @ΔημήτρηςΦιλίππου, I don't think so. My objective is to build an app in which the user inputs question through the form and gets an answer returned in the same web page. doc2vec_main.py should be called automatically in the background. It should take input and give output. – K. K. Jun 26 '17 at 10:38
  • 2
    then integrate your app to flask, why do you wanna make it seperate? flask is very extensible. import your file to flask main app and do your thing, plus handledata is not a global function , it is a Flask rule that only triggers when user sends a request – Dimitrios Filippou Jun 26 '17 at 10:40
  • @ΔημήτρηςΦιλίππου, then how should I make use of the userQuestion? – K. K. Jun 26 '17 at 10:42

3 Answers3

2

I found a possible solution. In your python script file import sys

when you run your script like this -> python doc2vec_main.py "question here"

you can access that variable through

>>> import sys
>>> print(sys.argv)
>>>['doc2vec_main.py', 'question here']

So then you can simply use this

document = sys.argv[1]

Okay we found the manuall way but you need to automate this with flask.

Inside flask app import os

and then when you want to execute your externall script do this

os.system("python doc2vec_main.py %s") % request.form['userQuestion']

You know this will work but wouldnt it be better to do this in one app only? it would be better.

  • I don't think this method will suit my purpose. I took your suggestion of integrating my python script to the flask and it worked. – K. K. Jun 26 '17 at 11:42
1
import gensim
import nltk
import numpy
from gensim import models
from gensim import utils
from gensim import corpora
from nltk.stem import PorterStemmer
ps = PorterStemmer()

# load the model here
model_loaded = models.Doc2Vec.load('my_model.doc2vec')

from flask import Flask, render_template, request
app = Flask(__name__)

@app.route('/')
def index():
   return render_template('init.html')

@app.route('/handle_data', methods = ['POST', 'GET'])
def handle_data():
    userQuestion = request.form['userQuestion']
    print(userQuestion)
    q_vector = doc2vec_main(userQuestion)
    return render_template('init.html', userQuestion = userQuestion)

def doc2vec_main(document):
    """whatever you want to do with your pre-trained doc2vec model can go here. I assume that doc2vec_main meant to return vector for a given document. for training part of the code you should write a separate function."""
    # your code here!
    return "replace this with your vector"

if __name__ == '__main__':
   app.run()
Mehdi
  • 4,202
  • 5
  • 20
  • 36
0

Put the script in another module of your Flask application, under a function that takes as argument the variable you want to process:

import gensim
import nltk
import numpy
from gensim import models
from gensim import utils
from gensim import corpora
from nltk.stem import PorterStemmer

def doc2vec(user_question):
    # your code here...

In your handle_data Flask view just pass the value from the form to your function. Take into consideration that this could not work in case your function is expensive so you can't wait for the result during normal request/response http flow.

BangTheBank
  • 809
  • 3
  • 11
  • 26