Create API with Flask that receives 2 strings and returns the similarity between them with spacy

Question:

I have this code that compute the similarity between 2 strings:

import spacy
from spacy.lang.pt.examples import sentences 

X ="some string 1"
Y ="some string 2"

nlp = spacy.load('pt_core_news_sm')
X_nlp = nlp(X)
Y_nlp = nlp(Y)

token_x = [token.text for token in X_nlp]
token_y = [token.text for token in Y_nlp]

print("Similarity:", X_nlp.similarity(Y_nlp))

Now I want to transform this code in an API with flask, I tried to follow a tutorial:

from flask import Flask,render_template,url_for,request
import re
import spacy
from spacy.lang.pt.examples import sentences 

nlp = spacy.load('pt_core_news_sm')

app = Flask(__name__)

@app.route('/',methods=["POST"])
def process():
    X_nlp = nlp(input())
    Y_nlp = nlp(input())
        
    print("Similarity:", X_nlp.similarity(Y_nlp))


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

the code above returns: "GET / HTTP/1.1" 405 –

Asked By: Carol Vieira

||

Answers:

You are trying to reach the URL "/". However, within your code there is no route defined for this path. Thus, the error 404 is returned.

You need a route that accepts both a GET and a POST request to both display a form and receive data from a submitted form sent via POST.
Otherwise, a 405 error is returned because the request method is not allowed.

@app.route('/', method=['GET', 'POST'])
def index():
    if request.method == 'POST':
         # Handle a POST request and the data sent here.
    # ...

Within Flask it is not possible to request input with input().
As mentioned above, you need a form within an HTML page. Within this form you can define input fields that must be provided with a name attribute in order to query them on the server side.

<form method="POST">
    <input type="text" name="x" />
    <input type="text" name="y" />
    <input type="submit">
</form>

If the submit button is now pressed, the data of the form, as defined in the method attribute, is sent to the server via POST and can be queried here. The input fields are queried using the name attribute.

Finally, the endpoint must have a return value. In your case, this is the template that displays the page with the form and outputs the possible result.

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        x = request.form.get('x', '')
        y = reutest.form.get('y', '')
        # ...
    return render_template('index.html')

So the entire code of your application should look something like this.

Flask (app.py)
from flask import (
    Flask,
    render_template,
    request
)
import spacy

nlp = spacy.load('pt_core_news_sm')

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        # Handle a POST request and the data sent here.
        x_nlp = nlp(request.form.get('x', ''))
        y_nlp = nlp(request.form.get('y', ''))
        
        resultado = x_nlp.similarity(y_nlp)
        
    # Return a rendered template and pass defined variables to the template.
    return render_template('index.html', **locals())
HTML (templates/index.html)
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Index</title>
</head>
<body>
    <form method="POST">
        <input type="text" name="x" />
        <input type="text" name="y" />
        <input type="submit">
    </form>

    {% if resultado -%}
    <p>Similaridade: {{ resultado }}</p>
    {% endif -%}
</body>
</html>
Answered By: Detlef
Categories: questions Tags: , , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.