pretty new to flask and ajax and was wondering if i could get some help. I am using python-twitter and want to be able to type in a search parameter that will search twitter for the requested word/words.
I have tried multiple solutions and both my friend and i can't see where it is going wrong. I can see the search variable being stored in ajax through a console.log but i can't get it to transfer that variable over to the twitter function that will search for the variable.
Here is my ajax:
$('#form').on('submit', function(e){
var search = $('#search').val();
e.preventDefault();
$.ajax({
url: '/twitter',
data: {'search': search},
method: 'Get',
success: function(result) {
// twit(data)
console.log(search)
}
});
});
And my Twit() As requested
#app.route('/twitter', methods=['GET', 'POST'])
def twit():
tempo = request.form['search']
searched = "Yes"
searched = request.args.get('search1')
# searched = request.form.get('number')
print(searched, file=sys.stderr)
api = twitter.Api(\
consumer_key='TWVxfrliliibQxjNWz4tAlDIj',
consumer_secret='QK2IBqNorysgD3quaBJVCMDdMApOpo5fW5g6Pl4Di97ToRjsGy',
access_token_key='3011394611-QmeEQ5yaL6OJTOmqemXV3eS0DpE09P0sy64XhnL',
access_token_secret='tEMygLkKBDwfVepHAg7G9BI7N8VQJM7U9KKefpV40jUq1'
)
count = "10"
data = api.GetSearch(
raw_query= 'q='+str(searched)+'&'
'count='+str(count)+'&'
'lang=en&'
'tweet_mode=extended&'
#'geocode=51.4027029,-0.3040634,10mi' #kington
)
print(data)
for i in data:
print('---------------------------')
if hasattr(i, 'retweeted_status'):
print(i.user.name + ': ' + i.full_text)
else:
print(i.user.name + ': ' + i.retweeted_status.full_text)
return(render_template('Twitter.html', d=data))
if __name__ == '__main__':
app.run(debug=True)
Here is the form
<form method="get" id="form">
<label for="search">Enter Search Parameter : </label>
<input type="text" id="search" name="search" autofocus autocomplete="off">
<button>Post</button>
</form>
The page should be updated using the searched for term.
Apologies if there is a very obvious mistake
Related
I'm following a tutorial to add new users to my database via a html form and flask. I'm able to run the code using the html template with: localhost/5000
But if I enter the data that should be add to the database I get the following error:
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
with this url: http://localhost:5000/sign_in?stage=login
Python code:
#app.route("/")
def showForm():
# show our html form to the user
t_message = "Python and Postgres Registration Application"
return render_template("register.html", message = t_message)
#app.route("/register", methods=["POST","GET"])
def register():
# get user input from the html form
t_email = request.form.get("t_email", "")
t_password = request.form.get("t_password", "")
# check for blanks
if t_email == "":
t_message = "Please fill in your email address"
return render_template("register.html", message = t_message)
if t_password == "":
t_message = "Please fill in your password"
return render_template("register.html", message = t_message)
# hash the password they entered
t_hashed = hashlib.sha256(t_password.encode())
t_password = t_hashed.hexdigest()
# database insert
t_host = "localhost"
t_port = "5432"
t_dbname = "register_dc"
t_user = "postgres"
t_pw = "=5.k7wT=!D"
db_conn = psycopg2.connect(host=t_host, port=t_port, dbname=t_dbname, user=t_user, password=t_pw)
db_cursor = db_conn.cursor()
# We take the time to build our SQL query string so that
# (a) we can easily & quickly read it
# (b) we can easily & quickly edit or add/remote lines
# The more complex the query, the greater the benefits
s = "INSERT INTO public.users "
s += "("
s += " t_email"
s += ", t_password"
s += ") VALUES ("
s += " '" + t_email + "'"
s += ",'" + t_password + "'"
s += ")"
db_cursor.execute(s)
try:
db_conn.commit()
except psycopg2.Error as e:
t_message = "Database error: " + e + "/n SQL: " + s
return render_template("register.html", message = t_message)
t_message = "Your user account has been added."
return render_template("register.html", message = t_message)
if __name__ == "__main__":
app.run(debug=True)
HTML code:
<script language="JavaScript" type="text/javascript">
function checkform (form)
{
/* isEmpty() returns true and alerts the user if they left a field empty */
function isEmpty (fixwhat, s_called)
{
if (fixwhat=="")
{
alert("Please enter " + s_called);
return true;
} else {
return false;
}
}
/* charCheck() returns false and alerts the user if they used any non-alphanumeric characters */
function charCheck(fixwhat)
{
var validchars = '#-_.0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
if(isValid(fixwhat,validchars))
{
return true;
} else {
alert("Please use only letters or numbers in this field");
return false;
}
}
/* isValid is used by the charCheck() function to look through each 'validchars' one at a time */
function isValid(string,validchars)
{
for (var i=0; i< string.length; i++)
{
if (validchars.indexOf(string.charAt(i)) === -1) {return false;}
}
return true;
}
// Check for empty fields
if (is_empty (form.t_email.value,"your email address")) { form.t_email.focus(); return false;}
if (is_empty (form.t_password.value,"your password")) { form.t_password.focus(); return false;}
//check for weird chars
if (charCheck(form.t_email.value)===false) {form.t_email.focus(); return false;}
if (charCheck(form.t_password.value)===false) {form.t_password.focus(); return false;}
return true ;
}
</script>
<div class='container'>
<form id='frmSignIn' name='frmSignIn' action='/sign_in?stage=login' method='post' onsubmit='return checkform(this);'>
<div class="form-row">
<label for="Email">Email address:</label>
<input type="text" id="t_email" name="t_email">
</div>
<div class="form-row">
<label for="Email">Password:</label>
<input type="text" id="t_password" name="t_password">
</div>
<div class="form-row">
<input type="submit" id="btn_submit_sign_in" value='Sign In'>
</div>
</form>
You are using the route /sign_in in your browser (and in your template), but you declared your route as /register, thus a 404 is returned.
I am new in Flask. My goal is to generate dynamic div containers every time I upload a dxf file and next submit happens. For example: one file uploaded- one div shown; two files uploaded- two divs shown and so on.
I can convert uploaded dxf files to .png images and I would like to show these images in div elements displayed after every upload.
I use input tag to upload files (type='file') and Java Script to generate dynamic elements (divs and their child tags).
The problem is that every time I upload file, the template is loading again and no new content is shown except the image of the last uploaded dxf. Please, give me a piece of advice to solve it.
HTML
...
<form enctype="multipart/form-data" id="uploadForm" action="/upload_files" name="uploadForm" method="post">
DXF file: <input type="file" id="dxfUpload" onchange="form.submit(); createConfigure();" name="dxfUpload" />
<div id="calcHolder" name="calcHolder">
<script type="text/javascript">
function createConfigure() {
var div = document.createElement("div");
div.id = "dxf-"+Math.random() * 100000000000000000 + "-"
+ window.performance.now() * 100000000000000000;
id_div=div.id;
div.className = 'border pad';
div.style.width = "640px";
div.style.height = "200px";
document.getElementById("calcHolder").appendChild(div);
var img = document.createElement("img");
img.setAttribute("src", "{{url_for('static', filename=dxfName+'.png')}}");
img.setAttribute("alt", "no image");
img.setAttribute("height", "120px");
img.setAttribute("width", "120px");
document.getElementById(id_div).appendChild(img);
var array = ["Carbon Steel","Stainless Steel","Aluminium"];
var selectMaterial = document.createElement("select");
document.getElementById(id_div).appendChild(selectMaterial);
for (var i = 0; i < array.length; i++) {
var option = document.createElement("option");
option.value = array[i];
option.text = array[i];
selectMaterial.appendChild(option);
}
var selectThickness = document.createElement("select");
document.getElementById(id_div).appendChild(selectThickness);
for (i = 1; i <= 16; i++) {
var opt = document.createElement('option');
//opt.value = i;
opt.innerHTML = i + ' mm';
selectThickness.appendChild(opt);
}
var quantity = document.createElement("input")
quantity.type="number";
quantity.value="1";
quantity.name="quantity";
quantity.min="1";
quantity.max="50";
quantity.onkeyup= function maxReach(){if(quantity.value > 50) quantity.value=50;};
document.getElementById(id_div).appendChild(quantity);
var btn = document.createElement("button");
btn.innerHTML = "Delete";
btn.type = "button";
document.getElementById(id_div).appendChild(btn);
btn.onclick = function() {div.remove();};
}
</script>
{{ html | safe }}
</div>
</form>
...
Python
#app.route('/upload_files', methods=['POST'])
def upload_files():
try:
if request.method == 'POST':
dxf_file = request.files['dxfUpload']
full_filename = os.path.join(app.config['UPLOAD_FOLDER'],dxf_file.filename)
dxf_file.save(full_filename)
first = DXF2IMG()
first.convert_dxf2img([full_filename],img_format='.png')
html="<img src="+url_for('static', filename=dxf_file.filename+'.png' )+" width='120' height='120' />"
return render_template('upload_files.html',dxfName=dxf_file.filename, html=html)
except:
...
#something happens
The result now
Desired result
Once the form.submit() function is executed, the form will be sent as a regular post request. For this reason, the following function is no longer executed and the entire page is reloaded.
In order to submit the form and change the content of the existing page, it is necessary to use AJAX.
This example shows you how to submit the form to the server and receive a JSON response containing the URLs of the received file and the generated image.
As soon as the submit button is pressed, the form data is packed into a FormData object and sent via AJAX using the fetch function. The browser's default behavior for a submit event is suppressed and the form is reset. The received file is processed by the server and the associated URLs are sent back to the client in JSON format. Now the document can be changed with the received data.
Remember this is just a minimal example to help you achieve your goals and implement your concept.
Flask (app.py)
import os
import ezdxf
from ezdxf.addons.drawing import matplotlib
from flask import Flask
from flask import (
jsonify,
make_response,
render_template,
url_for
)
from werkzeug.utils import secure_filename
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
def dxf2png(source, target):
doc = ezdxf.readfile(source)
msp = doc.modelspace()
auditor = doc.audit()
if auditor.has_errors:
raise Exception('Conversion failed.')
matplotlib.qsave(doc.modelspace(), target)
#app.route('/upload', methods=['POST'])
def upload():
if 'dxf-file' in request.files:
file = request.files['dxf-file']
if file.filename != '':
filename = secure_filename(file.filename)
filepath = os.path.join(app.static_folder, filename)
destname, _ = os.path.splitext(filename)
destname = f'{destname}.png'
destpath = os.path.join(app.static_folder, destname)
file.save(filepath)
try:
dxf2png(filepath, destpath)
except:
os.remove(filepath)
return make_response('', 400)
return make_response(
jsonify(
target=url_for('static', filename=filename),
preview=url_for('static', filename=destname)
),
200
)
return make_response('', 400)
HTML (templates/index.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Index</title>
<style media="screen">
.preview {
width: 120px;
height: auto;
}
</style>
</head>
<body>
<form name="dxf-upload" method="post" enctype="multipart/form-data">
<input type="file" name="dxf-file" />
<input type="submit" />
</form>
<div id="dxf-files"></div>
<script type="text/javascript">
((uri) => {
function createPreview(target, preview) {
const divElem = document.createElement('div');
divElem.innerHTML = `<img src="${preview}" class="preview" />`;
const outElem = document.getElementById('dxf-files');
outElem.append(divElem);
}
const form = document.querySelector('form[name="dxf-upload"]');
form.addEventListener('submit', evt => {
evt.preventDefault();
const formData = new FormData(evt.target);
fetch(uri, {
method: 'POST',
body: formData
}).then(resp => resp.json())
.then(data => {
const { target, preview } = data;
createPreview(target, preview);
});
evt.target.reset();
});
})({{ url_for('.upload') | tojson }});
</script>
</body>
</html>
I hope the title is enough to understand my problem, as you can see in the image below, i can get the pciture from my database, the problem is when I update the data and I didnt change the picture displayed, it makes an error, the cause of the error is I didnt get any data from html
<label for="myfile3">
<img id="output3" src="{{selectbanner.image.url}}" style="height:225px;width:250px;" class="subimage"/><br>
<input type="file" accept="myfile" id="myfile3" name="image" value="{{selectbanner.image.url}}" onchange="loadFile3(event)" >
</label>
<script>
var loadFile3 = function(event) {
var reader = new FileReader();
reader.onload = function(){
var output3 = document.getElementById('output3');
output3.src = reader.result;
};
reader.readAsDataURL(event.target.files[0]);
};
</script>
this is my views.py
image = request.FILES.get('image')
print(image)
update = Banner.objects.get(id=banner_id)
update.image = image
update.title = Title
update.sub_title = Sub
update.description = Description
update.save()
return redirect('Banners')
Firstly I would say you should refer to previously asked related questions.
Refer to these:
This
This
And this
I'm writing flask api using keras. However I get a lot of errors. One of them is Error 405 - method not allowed.
POST http://0.0.0.0:5000/static/predict 405 (METHOD NOT ALLOWED) jquery-3.3.1.min.js
I'm trying to get predictions written on the page, but they didn't show even before that error 405.
I don't know which place can lead to that error.
Here is code:
predict.html
<body>
<input id="image-selector" type="file">
<button id="predict-button"> Predict</button>
<p style="font-weight:bold">Predictions</p>
<p> Jablko <span id="apple-prediction"></span></p>
<p> Banan <span id="banana-prediction"></span></p>
<img id="selected-image" src=""/>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
let base64Image;
$("#image-selector").change(function(){
let reader = new FileReader();
reader.onload = function(e){
let dataURL = reader.result;
$('#selected-image').attr("src", dataURL);
base64Image = dataURL.replace("data:image/jpg;base64,", "");
//console.log(base64Image);
}
reader.readAsDataURL($("#image-selector")[0].files[0]);
$("#apple-prediction").text("");
$("#banana-prediction").text("");
});
$("#predict-button").click(function(event){
let message = {
image:base64Image
}
//console.log(message);
$.post("http://0.0.0.0:5000/static/predict", function(response){
$("#apple-prediction").text(response.prediction.apple.toFixed(6));
$("#banana-prediction").text(response.prediction.banana.toFixed(6));
console.log(response);
});
});
</script>
</body>
predict.py
app = Flask(__name__)
def get_model():
global model
model=load_model('fc_model1.h5')
#model.load_weights('model_grocery.h5')
#graph = tf.get_default_graph
print("** Model loaded!")
def preprocess_image(image, target_size):
image = image.resize(target_size)
image = image.img_to_array(image)
image = np.expand_dims(image, axis=0)
return image
print("**Loading model**")
get_model()
#app.route("/predict", methods=["POST"])
def predict():
message = request.get_json(force=True)
encoded = message['image']
decoded = base64.b64decode(encoded)
image = Image.open(io.BytesIO(decoded))
processed_image = preprocess_image(image, target_size=(224, 224))
#bt_prediction = vgg16.predict(processed_image)
prediction = model.predict(processed_image).tolist()
response = {
'prediction': {
'apple': prediction[0][0],
'banana': prediction[0][1]
}
}
return jsonify(response)
The error shows in google-chrome.
Your JS code has
$.post("http://0.0.0.0:5000/static/predict")
but your Flask route is
#app.route("/predict", methods=["POST"])
def predict():
Because the snippet you posted doesn't show that you're prepending /static/ to all routes, it looks like that's a mistake.
You specified methods=['POST'] correctly, so visiting 127.0.0.1:5000/predict should yield the expected result.
If you wanted to check 0.0.0.0:5000/predict, you need to add app.run(host='0.0.0.0')(See: Configure Flask dev server to be visible across the network).
New to Python and Django and I'm trying to make a simple ajax call from a button click to pass certain data to my views.py, however, when I try to make a url as seen on my ajax code below, the documentId.id does not append unless I directly append in without the "?id=".
{%for document in documents%}
{{document.filename}}
<input type="button" id="{{document.id}}" onclick="loadData(this)" name="load-data" value="Add"/>
{%endfor%}
<script type ="text/javascript">
function loadData(documentId){
$.ajax({
url:"upload-data/load" + "?id=" + documentId.id,
data: {'documentId': documentId},
type: 'GET',
success: function(){
window.location.href = "http://127.0.0.1:8000/url/locations";
}
});
}
</script>
This gives me then an error that says the url cannot be found. I have a line in my urls.py below:
url(r^"upload-data/load/([0-9]+)/$', views.loadFile, name="load-data"),
Other than this method, I am stumped as to how I am going to extract my data to my views.py.
def loadFile(request):
documentId = request.GET.get('id')
newLayer = Layer(get_object_or_404(Document, pk = documentId))
newLayer.save()
layers = Layer.objects.all()
return render(request, 'url/loaded.html', { 'layers': layers})
The persisting error in the console would be:
http://127.0.0.1:8000/upload-data/load/ [HTTP/1.0 404 Not Found]
Use something like this:
def loadFile(request):
documentId= request.GET.get('id', '').
newLayer = Layer(get_object_or_404(Document, pk = documentId))
newLayer.save()
layers = Layer.objects.all()
return render(request, 'url/loaded.html', { 'layers': layers})
And update your url as :
url(r^"upload-data/load/', views.loadFile, name="load-data")
And the script would be like :
<script type ="text/javascript">
function loadData(documentId){
$.ajax({
url:"upload-data/load/?id="+ documentId.id,
data: {'documentId': documentId},
type: 'GET',
success: function(){
window.location.href = "http://127.0.0.1:8000/url/locations";
}
});
}
</script>
Thanks.
In JavaScript you need
"upload-data/load/" + documentId.id
Django doesn't use ?id= in url definition r^"upload-data/load/([0-9]+)/$'. It expects ie. upload-data/load/123 instead of upload-data/load?id=123
EDIT: and you need id in def loadFile(request, id).
And then you don't have to use request.GET.get('id')
From the above answers and comments it seems like rather than passing id as a url param you want to pass the same as a get param. In that case make your urls like below.
url(r^"upload-data/load/', views.loadFile, name="load-data")
and in views, check for get params by replacing id with documentId. document id will be in your dict named as data passed to view. So look for request.GET.get('data','') and from data extract id as below
def loadFile(request):
data = request.GET.get('data', None)
if data:
documentId = data['documentId']
newLayer = Layer(get_object_or_404(Document, pk = documentId))
newLayer.save()
layers = Layer.objects.all()
return render(request, 'url/loaded.html', { 'layers': layers})
else:
return JsonResponse({'error': 'pass document id'}, status=400)
Since you are passing a get param from javascript named as documentId not id.
HTH