I have an old application based on Python SimpleHTTPServer that I'm trying to convert to Flask.
In the old application, I had an HTML form that was submitting a POST request to the SimpleHTTPServer. The form also had an iframe. There, I had a do_POST method that was reading the values in the text boxes and producing some results. I then wrapped the results into a JSON object and wrote to the wfile method of SIMPLEHTTPServer. This caused the result to get populated into the iframe. The iframe had an onload method on the JS side and here, the results would be read from it and populated into various text-boxes.
I now want to convert this to Flask from SimpleHTTPServer. What is the best way to translate the logic I have in place to Flask? Basically, what is the equivalent of writing to the wfile object?
Also, on the Flask side, I also have some #app.route methods where I can form a URL with input parameters and get the results as JSON objects (example: http://localhost/calculate?input1=3&input2=5). Is it possible to leverage these URLs instead of the POST request to get the result into JavaScript?
Here is hello world of flask to get the data from URL parameters and do the stuff and return a json
from flask import Flask, jsonify, request
app = Flask(__name__)
#app.route('/')
def hello_world():
param1 = request.args.get('param1')
param2 = request.args.get('param2')
res = param1 + param2
return jsonify({
"result": res
})
if __name__ == '__main__':
app.run()
example request
GET http://127.0.0.1:5000/?param1=hi¶m2=there
Example response
{
"result": "hithere"
}
Related
I am following this tutorial to communicate between python and javascript. I am a beginner to this so I dont understand what exactly I am doing wrong.
Following is my code in index.html which sends a POST request to the python server side when the button is clicked:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script type="text/javascript">
// setup some JSON to use
var cars = [
{ "make":"Porsche", "model":"911S" },
{ "make":"Mercedes-Benz", "model":"220SE" },
{ "make":"Jaguar","model": "Mark VII" }
];
window.onload = function() {
// setup the button click
document.getElementById("theButton").onclick = function() {
doWork()
};
}
function doWork() {
console.log("posting data")
// ajax the JSON to the server
$.post("receiver", cars, function(){
});
// stop link reloading the page
event.preventDefault();
}
</script>
This will send data using AJAX to Python:<br /><br />
<button type="button" id="theButton">Click Me!</button>
And this is my code on the python side:
import sys
from flask import Flask, render_template, request, redirect, Response
import random, json
app = Flask(__name__)
#app.route('/')
def output():
# serve index template
return render_template('index.html', name='Joe')
#app.route('/receiver', methods = ['GET', 'POST'])
def worker():
print("got some data")
# read json + reply
data = request.get_json()
result = ''
for item in data:
# loop over every row
result += str(item['make']) + ''
return result
if __name__ == '__main__':
app.run()
So, when I press the button in the index.html file, the tutorial says that I will be able to see a server response in the web browser. But even though my server is running, this is what I see in the network tab of developer tools for index.html in the Firefox web browser:
I don't understand what I am doing wrong and how I am supposed to see the communication between the client and server. Any help would be appreciated
Your request is not sending JSON, you have to stringify the cars object to send it as JSON.
function doWork() {
console.log("posting data")
// ajax the JSON to the server
$.post("receiver", JSON.stringify(cars), function(){
}, 'application/json');
// stop link reloading the page
event.preventDefault();
}
I also set the content type to application/json as this is required by request.get_json().
For your network tab issue, you have JS selected so you would not see ajax requests only javascript files. You have to have XHR selected or All.
I need to insert in a response information in the body of this with c#.
Currently I have a function that inserts a custom message in an HttpResponseMessageProperty object which is validated from the web client observing response.statusText.
When accessing from https we discover that this data is not being sent since the requests are being made from http \ 2.
Instead of how we are sending it, I would like to know in what way I could send that data through the body.
The following code works with http 1.1. And response is of class Message
if (message.Length > 0) {
property.StatusDescription = message
}
response.Properties[HttpResponseMessageProperty.Name] = property;
Later that Message object is returned through RequestContext Reply.
How can I include data that I can later read from response.data in javascript?
Thank you all
EDIT:
I'm using Net Framework 3.5
Context: I am using JavaScript to send a string as a parameter to a python function over the flask.
But I always get "the missing 1 parameter error" on the python side.
This is what my Ajax query looks like:
$.ajax({
url : 'ListMaker',
data: 'Q1',
success: function(data) {
//does something
}
});
This is what my python function looks like:
#app.route("/ListMaker",methods=["POST","GET"])
def ListMaker(text):
#make it a string just incase
quarter=str(text)
//do things with string
Any other similar questions I can find online, only talk about issues with Ajax and don't really cover the python side. In my case, the function is clearly being called, but it claims to receive no data to work with.
Am I sending the data wrongly from the Ajax side? Or am I parsing it wrongly on the python side?
Clarification for NoneType error from the comments below:
I am sending over:
data: JSON.stringify({"letter": "Q", "value": "25%"})
I am receiving it on the python side like so:
data=request.get_json()
letter=data["letter"]
value=data["value"]
The parameters in a Flask route are for variables in the path, called "variable rules" in Flask:
#app.route("/ListMaker/<text>", methods=["POST", "GET"])
def ListMaker(text):
...
As jQuery Ajax requests are GET by default, your data will be converted to a query string, in this case /ListMaker?Q1. You can access the query string in Flask with flask.request.args.
However, query strings are key-value, and you are only supplying a key, which will correspond to the Python dict {'Q1': ''}. You should either set the Ajax data to a string like quarter=Q1, or use an object:
$.ajax({
url : 'ListMaker',
data: {'quarter': 'Q1'}, // or 'quarter=Q1'
success: function(data) {
//does something
}
});
Then you will be able to access it in Flask:
#app.route("/ListMaker", methods=["POST", "GET"])
def ListMaker(): # no parameters needed
quarter = flask.request.args["quarter"]
# quarter == "Q1"
If you want to use a POST request, set method: 'POST' in the Ajax-call, and use flask.request.get_data() or flask.request.get_json() on the Flask side.
I have a website that should send a name to a python script (on a third-party website) when a button is pressed. This python script will then make the name uppercase and return it back to the website.
Right now an XMLHttpRequest is correctly being sent when the button is pressed, but I'm unsure how I correctly send the data with the XMLHttpRequest, and then how this data is accessed in the python script.
XMLHttpRequest:
document.getElementById("myButton").addEventListener("click",
function() {
var myRequest = new XMLHttpRequest();
myRequest.open('GET', 'https://example.com/');
myRequest.onreadystatechange = function () {
if (myRequest.readyState === 4) {
alert(myRequest.responseText);
}
}
myRequest.send("Bob"});
}
);
Python script:
from flask import Flask, jsonify
from flask_cors import CORS
from requests import request
app = Flask(__name__)
CORS(app)
#app.route("/", methods=["GET"])
def hello_world():
return jsonify(name = (name_sent_by_XMLHttpRequest).upper()) # Should return "BOB"
if __name__ == '__main__':
app.run()
I know nothing about javascripts' XMLHTTPRequest but at some point, you need to send the name to the python server, right? HOW to do that is up to you, but a GET based option:
GET request with args: https://example.com/?name=your_name_goes_here
in your flask app, the function listening on route "/" will now have access to that arg, something like
name = request.args.get('name', '')
then you can uppercase() it, and return it in some format - probably XML ?
return Response(my_xml, mimetype='text/xml')
Update based on your comment: usually in a flask function, you would use the flask request object to get your URL parameters. In your example, you're importing the requests module as request, not using it, but clobbering the flask.request namesspace. Change your imports to something like this, and it should work normally:
from flask import Flask, jsonify, request
from flask_cors import CORS
import requests
I'm actually working with flask.
I use flask in order to run a server, which will be requested by a chrome extension (js).
Requesting the server from the extension is quite simple : I use the chrome.runtime.sendMessage() method. This method provides also a callback function, taking as parameters a JSON object (the response from the server).
E.g, suppose that I have this route on my server :
#app.route('/users', methods=['POST'])
def api_login():
if 'username' not in request.json :
return jsonify(success=false)
else :
return jsonify(success=true)
Then, I can in my extenstion, and more precisely in the callback function, check the success value :
function(response) {
if(response.success){
console.log("Login ok !")
}
}
But now, my team doesn't want rely on this anymore, and wants to use http error code instead. I know that flask has an abort function, but while reading the documentation, I have had a lot of trouble to understand what it really does. When I call in my route :
else:
abort(422, {"error":"Missing parameters"})
how can I use these information on the extension (js) ? Does flask automatically returns a specific JSON object when abort is called ? How can I check the error code ? I would like to do something like that in the client code :
if(response.status == 422) {
console.log("Error")
}
One of the clues I have, reading all the StackOverflow threads about abort() is to define a specific error function using the decorator #app.errorhandler(code) :
#app.errorhandler(422)
def myErrorCase(error):
return jsonify(status=422, error="missing parameters")
But I assume that there are more straightforward ways.
Thanks for your help.
Note that i'm using JQuery for this example because it's easier and saves you from a lot of stress and cross-browser issues.
If you just pass in the error code like you're already doing, Werkzeug wraps the error message in html (Though you can still use regex to extract the error message on the client side, but that isn't really flexible). So No Flask doesn't automatically return a JSON string back to the client
The flask abort method either accepts an error code or it can accept a Response object. To achieve what you want to do, you have to pass a Response object to the abort method.
The Response Object is a wrapper around the werkzeug.wrappers.Response object
There also a helper method to create a response object called make_response so you don't have to fiddle with the Response class if you just want to create a simple Response object
One of the reasons you'll create a Response object instead of allowing render_template or abort do it for you is when you need to add a custom header to a response or change the default headers that abort adds to the response.
app.py
from flask import Flask, abort, render_template, Response
from json import dumps
app = Flask(__name__)
#app.route('/')
def home():
return render_template('client.html')
#app.route('/resource')
def resource():
error_message = dumps({'Message': 'You cannot see this!!!'})
abort(Response(error_message, 401))
if __name__ == '__main__':
app.run()
client.html
<html>
<head>
<title></title>
<meta content="">
<style></style>
<script
src="https://code.jquery.com/jquery-3.1.1.min.js"
integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
crossorigin="anonymous">
</script>
</head>
<body>
<script>
$.ajax({
url: 'http://localhost:5000/resource',
dataType: 'json',
success: function(data){
alert('Your request was successful');
},
statusCode: {
401: function (response) {
error = JSON.parse(response.responseText)
alert(error.Message)
}
}
});
</script>
</body>
</html>
You can handle different error codes by defining a corresponding function for them under statusCode
You can still do this from pure Javascript, It just involves more keystrokes.
You should really read through werkzeug's source code to get a better understanding on how abort and exceptions are generally handled. This would be a good starting point