How to execute Python program within #app.route without 405 error? - python

I am trying to execute this python back end program once I reach the handle data page. Why are the methods returning a 405 Method Not Allowed error?
In the past, I've tried changing the position of the python to outside of the # decorator and the methods=["POST"] condition
Python
import random
import requests
import time
from datetime import date
import sys
import re
import json
from bs4 import BeautifulSoup
from flask import Flask, render_template, jsonify
app = Flask(__name__)
#app.route("/")
#app.route("/home")
def home():
return render_template('home.html')
#app.route("/handle_data")
def handle_data():
userName = requests.form['username']
listName = requests.form['listname']
full python code is here
randomNumber = randint(0,len(nameList)-1)
films = nameList[randomNumber]
return render_template('home.html', films=films)
if __name__ == '__main__':
app.run(debug=True)
...
HTML
<form action="{{ url_for('handle_data') }}" method="POST">
<form>
<div class="form-row">
<div class="col">
<input type="text" size=15 name=username class="form-control" placeholder="Username">
</div>
<div class="col">
<input type="text" size=15 name=listname class="form-control" placeholder="List Name">
</div>
</div>
<p><input type = "submit" class="buttonclass" value = "Random!" /></p>
</form>
I expect the program to run the requests from the form through the program and return the random list item in form of the variable "films" but I receive a 405 error.
If you need more info, please notify

#app.route("/handle_data") registers the route only for GET requests. If you want POST too, you need to ask for it explicitly:
#app.route("/handle_data", methods=['GET', 'POST'])
def handle_data():
# your code here
or:
#app.route("/handle_data", methods=['GET'])
def handle_get_data():
pass
#app.route("/handle_data", methods=['POST'])
def handle_post_data():
pass
More here: http://flask.pocoo.org/docs/1.0/api/#url-route-registrations

Related

How to keep same page in Flask

this is a very simple code with Flask. Every time I click submit I go to another page and I lose my input field and my button.
I wonder HOW I can keep the same page and have just a refresh of the page when I have the output. Or if there is any other solution. Thank you
from flask import Flask, render_template_string, request
app = Flask(__name__)
html = """
<div class="form">
<form action="{{url_for('sent')}}" method="POST">
<input title="Title" placeholder="Enter something" type="text" name="line" required> <br>
<button class="go-button" type="submit"> Submit </button>
</form>
</div>
"""
#app.route("/")
def index():
return render_template_string(html)
#app.route("/", methods=['GET', 'POST'])
def sent():
line = None
if request.method == 'POST':
line = request.form['line']
return line
if __name__ == "__main__":
app.run(debug=True)
You can redirect back to the original page after processing the input
Instead of
return line
You can
from flask import redirect, url_for
return redirect(url_for("index"))

Flask Application Showing 404 on Post

This is my first attempt at deploying a machine learning application and also my first time using flask. Essentially the user will fill out a form on an html page and the input from the form will be used as input to the machine learning model which is saved in a pickle file, model.pkl in the code below. I am running into one snag that I can't seem to break past..
Every time I submit from index.html and post to result.html I'm receiving a 404 error.
script.py:
#importing libraries
import os
import numpy as np
import flask
import pickle
from flask import Flask, render_template, request
app=Flask(__name__)
#app.route('/')
#app.route('/index')
def index():
return flask.render_template('index.html')
def ValuePredictor(to_predict_list):
to_predict = np.array(to_predict_list).reshape(1,12)
loaded_model = pickle.load(open("model.pkl","rb"))
result = loaded_model.predict(to_predict)
return result[0]
#app.route('/result',methods = ['POST'])
def result():
if request.method == 'POST':
to_predict_list = request.form.to_dict()
to_predict_list=list(to_predict_list.values())
to_predict_list = list(map(int, to_predict_list))
result = ValuePredictor(to_predict_list)
if int(result)==1:
prediction='Income more than 50K'
else:
prediction='Income less that 50K'
return render_template("result.html",prediction=prediction)
index.html:
<html>
<body>
<h3>Income Prediction Form</h3>
<div>
<form action="/result.html" method="POST">
<label for="age">Age</label>
<input type="text" id="age" name="age">
<br>
<label for="edu">Education</label>
<select id="edu" name="edu">
<option value="0">High School</option>
<option value="1">College Degree</option>
</select>
<br>
<label for="martial_stat">Marital Status</label>
<select id="martial_stat" name="martial_stat">
<option value="0">not married</option>
<option value="1">married</option>
</select>
<br>
<label for="gender">Gender</label>
<select id="gender" name="gender">
<option value="0">Female</option>
<option value="1">Male</option>
</select>
<br>
<input type="submit" value="Submit">
</form>
</div>
</body>
</html>
result.html:
<html>
<body>
<h1> {{ prediction }}</h1>
</body>
</html>
I can't seem to figure this out. My code never seems to reach the first line in the result() function. As soon as I submit from index.html http://127.0.0.1:5000/result.html throws a 404 error. Any suggestions?
The error is very simple here, the action property in index.html should just be
<form action="/result" method="POST">
instead of
<form action="/result.html" method="POST">
You want to use /result to go through your flask function. Hope this helps!
You are posting to the endpoint /result.html:
<form action="/result.html" method="POST">
... but your route in flask is defined as /result (with no .html):
#app.route('/result',methods = ['POST'])
def result():
...
These two need to match, so consider changing the route to result.html.
Instead of <form action="/result.html" method="POST">
Can Use <form action="{{ url_for('result') }}" method="POST">

How to print/Display my search results on the same webpage using Flask and HTML?

I have a dataset of Players and the number of goals they have scored, this dataset is stored in a dataframe. I want to display or print the stats and player details that I have searched for on the search bar, but I am always getting a bad request error
This is the dataset Dataset Screenshot
this is how the Webpage looks like Webpage screenshot
MainProject Python file
import pandas as pd
from pandas import DataFrame
from fuzzywuzzy import process
scorers=pd.read_csv('tests.csv')
def main(searchplayer):
scorers=pd.read_csv('tests.csv')
player=list(scorers['Player'])
goals=list(scorers['Goals'])
team=list(scorers['Team'])
df_data={'player': player,
'goals': goals,
'team': team}
df_main=pd.DataFrame(df_data, columns=['player', 'goals', 'team'])
def getSearchedProducts(searchplayer, choices, limit=30):
res=process.extract(searchplayer, choices, limit=limit)
return res
searchplayer=str(searchplayer)
result=getSearchedProducts(searchplayer, player)
player_result_list = [res[0] for res in result if res[1]>=70]
player_result_df = df_main[df_main['Product'].isin(product_result_list)]
player_result_df.index+=1
list_player_res=[(tabulate(player_result_df, headers='keys', tablefmt='psql'))]
return list_player_res
Flask File
import os
from flask import Flask, flash, request, render_template,
redirect, url_for, send_from_directory
from werkzeug.utils import secure_filename
from MainProject import main
from flask_cors import CORS
searchplayer=""
app=Flask(__name__)
app.config['CACHE_TYPE']='null'
CORS(app)
#app.route('/', methods=['GET', 'POST'])
def homepage():
searchplayer=request.form['prod']
list_player_res = main(searchplayer)
return render_template('home.html', list_player_res=list_player_res)
if __name__ == "__main__":
app.run()
A code snippet of my Html file
<form class="form-inline" method="POST">
<input class="form-control mr-sm-2" name="prod" type="search" placeholder="Search for Players" aria-label="Search">
<button class="btn btn-light my-sm-0" type="Submit">Search</button>
</form>
This is what I tried:
#app.route('/')
def homepage():
return render_template('home.html')
#app.route('/searchpg', methods=['GET', 'POST'])
def searchpg():
global searchplayer
if request.method == 'POST':
searchplayer = request.form.get['prod']
list_res, list_prod_res = main(searchplayer)
print(list_player_res)
return render_template('home.html', list_player_res=list_player_res)
HTML This is what I did:
<form class="form-inline" method="POST">
<input class="form-control mr-sm-2" name="prod"
type="search" placeholder="Search for Players" aria-label="Search">
<button class="btn btn-light my-sm-0"
type="Submit">Search</button>
</form>
</div>
</nav>
<br>
{% for result in list_player_res %}
{{result}}
{% endfor %}
</br>
How do I search for players in that searchbar and the results get displayed on the same screen?

session.get('name') returns none, not form data

I have done a lot of research through multiple posts about this issue, and and no matter what I try I am getting issues. Essentially what I am trying to do it write something in an input field, press a submit button and post the string from the input field and display it on a separate page/separate route in using flask. I think I am on the right track with what I have below, however it returns a value of None rather than what I write in my input field in index.html.
from flask import Flask, render_template, request, jsonify, Response,
redirect, url_for,session
from flask_bootstrap import Bootstrap
app = Flask(__name__)
Bootstrap(app)
app.secret_key = 'dljsaklqk24e21cjn!Ew##dsa5'
#app.route('/', methods=['GET', 'POST'])
def hello():
if request.method == 'POST':
nme = request.form['name']
session['name'] = nme
return url_for(deliver)
return render_template('index.html')
#app.route('/delivery', methods=['GET', 'POST'])
def deliver():
name = session.get('name')
return render_template('delivery.html', name=name)
index.html is
<form action = "{{ url_for('deliver')}}" method = "POST">
<p>Name <input type = text class="form-control" name = "name" /></p>
<p>Address <input type = text class="form-control" name = "Address" /></p>
<input type=submit name='submit'>
</form>
and delivery.html is
<div class="card-deck mx-auto" style="width: 75rem;">
<div class="card text-white bg-dark p-3" style="width: 45rem;">
<h5 class="card-title text-center"></h5>
<img class="card-img-top mx-auto" src="/static/img/hands.png" alt="Vibration
Image" style="width:20%">
<div class="card-body">
<h2 class="card-title text-center">Delivery Information</h2>
<h5> {{name}} </h5>
This code:
<form action = "{{ url_for('deliver')}}" method = "POST">
means that submitting the form will POST to /deliver, but you really want to POST to the index page to trigger the session['name'] = nme code. So just remove the action.
You also need to change
return url_for(deliver)
to
return redirect(url_for('deliver'))

Employing Post Method in Flask

Using the following:
from flask import Flask, render_template
import beautiful_soup_tidal
app = Flask(__name__)
#app.route('/')
def form():
return render_template('form_submit.html')
#app.route('/richmond', methods=['POST'])
def richmond():
someTides = beautiful_soup_tidal.getTides()
return render_template('richmond.html',someTides=someTides)
if __name__ == "__main__":
app.run(debug=True)
And attempting to render the following (richmond.html):
<div id="content" class="form-group">
<form method="post" action="/richmond">
<label style="vertical-align: middle;">channel depth at mean low water
<input type="number" step="0.1" value = "34.5" name="channelDepth"/>FEET</label><br><br>
<label style="vertical-align: middle;">required underkeel clearance
<input type="number" step="0.1" value = "2" name="underkeelClearance"/>FEET</label><br><br>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
I get the following error: 'The method is not allowed for the requested URL.'
If I delete ', methods=['POST']' in the first section the template renders.
The question: How do I render the template successfully using the post method?
i believe this line should also include GET so that you can render the html form first time round before you actually click submit to post it.
#app.route('/richmond', methods=['POST'])
so it would change to
#app.route('/richmond', methods=['GET', 'POST'])

Categories

Resources