Use jquery and Flask to print input but print nothing - python

I just learn flask to use with jquery, just want to print out what i typed in , but it print nothing
here is html code
<body>
<input id="name-input" type="text" />
<button id="name-button">Submit Name</button>
<p id="greeting"></p>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
$("#name-button").click(function (event) {
let message = {
name: $("#name-input").val()
}
$.post("http://10.0.0.4:5000/hello", JSON.stringify(message), function (response) {
$("#greeting").text(response.greeting);
console.log(response);
});
});
</script>
</body>
here is flask code:
from flask import request
from flask import jsonify
from flask import Flask
app = Flask(__name__)
#app.route('/hello',methods=['POST'])
def hello():
message = request.get_json(force=True)
name = message['name']
response = {
'greeting': 'Hello, ' + name + '!'
}
return jsonify(response)
when i click button, it print nothing!. please help, thank a lot

Two issues:
You're using the IP address shown in the example, which is very unlikely to point to your own PC on a network. More likely is 127.0.0.1:5000/hello, which would be localhost if you're running through the dev server. You can actually run the server across the network by providing the --host=0.0.0.0 flag to flask run. NOTE: This is only for the development server; you'll want to look at deployment options when you run this for real
Your route only accepts POST requests, but you're sending a GET request
The HTMl:
<body>
<input id="name-input" type="text" />
<button id="name-button">Submit Name</button>
<p id="greeting"></p>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
$("#name-button").click(function (event) {
let message = {
name: $("#name-input").val()
}
$.post("http://127.0.0.1:5000/hello", JSON.stringify(message), function (response) {
$("#greeting").text(response.greeting);
console.log(response);
});
});
</script>
</body>
The route:
#app.route('/hello',methods=['GET', 'POST'])
def hello():
message = request.get_json(force=True)
name = message['name']
response = {
'greeting': 'Hello, ' + name + '!'
}
return jsonify(response)

Related

Trying to use jQuery to read a file in Python Flask web application

I have a flask and Python application where I have a Templates directory to hots an index.html
that I render using
#app.route("/")
def home():
return render_template('index.html')
that works fine , but the web page index.html uses jquery to read a json file and for some reason it cannot read it in the FLASK webserver environment
the json file is in a folder called ./curldata and the rendered html file is in a folder ./Templates at the same level
the error I get in developer tools ie:
jquery-3.5.0.js:10099 GET http://127.0.0.1:5000/curldata/views.json 404 (NOT FOUND)
send # jquery-3.5.0.js:10099
ajax # jquery-3.5.0.js:9682
jQuery.<computed> # jquery-3.5.0.js:9836
getJSON # jquery-3.5.0.js:9817
(anonymous) # (index):6
(anonymous) # (index):18
see index.html below:
<html>
<head>
<script src="https://code.jquery.com/jquery-3.5.0.js"></script>
<script>
(function() {
$.getJSON( "../curldata/views.json", function( data ) {
var items = [];
$.each( data, function( key, val ) {
items.push( "<li><a href='" + val + "'>" + val + "</a></li>" );
});
$( "<ul/>", {
"class": "my-new-list",
html: items.join( "" )
}).appendTo( "body" );
});
})();
</script>
</head>
<body>
BODY:</br>
</body>
</html>
I am an idiot , first off I am embedding the front end in the backend
then I was'nt even using the backend
$.getJSON( "/views", function( data ) {
changing this line is the answer since the flask server is providing the json
sorry about that

Post form data from React handle submit function to python API?

I'm extremely new to React and Python and just trying to do a simple post from a react form to my Python API that will interface with a mongoDB.
I have a form in react that invokes a handleSubmit function on submit. I want the handleSubmit function to POST to my Python API running on port 5000. My react app is running on port 8080.
The handleSubmit looks like this:
handleSubmit(event) {
const axios = require('axios');
const baseUrl = 'http://localhost:5000'
axios.post('http://localhost:5000/api/create', JSON.stringify(params))
.end((error, response) => {
if (!error && response) {
console.log('got a valid response from the server')
} else {
console.log(`Error fetching data from the server: `, error)
}
});
event.preventDefault();
}
Python endpoint code:
#app.route('/api/create', methods=['POST'])
def create(self):
if request.method == 'POST':
print(request.args.get('exp_title'))
return True
return False
When I click the button, my python API endpoint isn't reached because react is trying to post to a route on port 8080. What am I missing?
I've tried using a regular ajax call and get the same result. At one point, I did something and got a CORS error in the browser, but I can't remember how I did that.
To enable cors, you need to install pip install -U flask-cors,
here is the website: https://flask-cors.readthedocs.io/en/latest/
or you can define cors in proxy in your reactjs package.json like here:
https://facebook.github.io/create-react-app/docs/proxying-api-requests-in-development
Once you install cors in your python app, try this:
Python app:
#app.route('/api/', methods=['POST', 'GET'])
def api_post():
if request.method == 'POST':
print('post app')
req = request.json
print(req)
return jsonify(name='john')
React app:
function App() {
const [todos, setTodos] = useState(null);
const [value, setValue] = useState('');
function handleSubmit(e) {
e.preventDefault();
const data = { name: value };
console.log('submit');
console.log(value);
fetch('http://127.0.0.1:5000/api/', {
method: 'POST',
headers: {
'Content-type': 'application/json',
},
body: JSON.stringify(data),
})
.then(res => res.json())
.then(res => console.log(res));
}
function handleValue(e) {
setValue(e.target.value);
}
return (
<section id="app">
<form action="" onSubmit={handleSubmit}>
<input type="text" onChange={handleValue} />
<button> submit </button>
</form>
</section>
);
}
render(<App />, document.querySelector('#root'));

Can't figure out how to implement Google Sign in with oAuth2

I am trying to create a login function for a web application and have been following the guide set out here https://developers.google.com/identity/sign-in/web/server-side-flow
I have followed the instructions mostly copying everything and replacing it with my information. I want to keep it as basic as possible so I can understand what is happening.
Here is my Python application for the authentication. I think I have done the http request wrong, as I had to find other examples because it's not explained on the google website.
The website should send the auth_code to http://localhost:5000/auth_code and the web.py should listen for it and if it is successful print out the email.
web.py
from apiclient import discovery
import httplib2
from oauth2client import client
import json
h = httplib2.Http(".cache")
resp, content = h.request("http://localhost:5000/auth_code", "GET")
auth_code = content
print (auth_code)
CLIENT_SECRET_FILE = '*****.apps.googleusercontent.com.json'
credentials = client.credentials_from_clientsecrets_and_code(
CLIENT_SECRET_FILE, ['https://www.googleapis.com/auth/drive.appdata', 'profile', 'email'],
auth_code)
http_auth = credentials.authorize(httplib2.Http())
drive_service = discovery.build('drive', 'v3', http=http_auth)
appfolder = drive_service.files().get(fileID='appfolder').execute()
userid = credentials.id_token['sub']
email = credentials.id_token['email']
print (email)
This is the python app for serving the webpage.
host.py
from flask import Flask, render_template, request
app = Flask(__name__)
#app.route('/') def index():
return render_template('index.html')
if __name__=="__main__": app.run(debug=True)
This is the HTML for the webpage.
<!-- The top of file index.html --> <html itemscope itemtype="http://schema.org/Article"> <head> <!-- BEGIN Pre-requisites --> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"> </script> <script src="https://apis.google.com/js/client:platform.js?onload=start" async defer> </script> <!-- END Pre-requisites --> <!-- Continuing the <head> section --> <script>
function start() {
gapi.load('auth2', function() {
auth2 = gapi.auth2.init({
client_id: '****.apps.googleusercontent.com',
// Scopes to request in addition to 'profile' and 'email'
//scope: 'additional_scope'
});
});
} </script> </head> <body> <!-- ... --> <!-- Add where you want your sign-in button to render --> <!-- Use an image that follows the branding guidelines in a real app --> <button id="signinButton">Sign in with Google</button> <script> $('#signinButton').click(function() {
// signInCallback defined in step 6.
auth2.grantOfflineAccess({'redirect_uri': 'postmessage'}).then(signInCallback); }); </script> <script> function signInCallback(authResult) { if (authResult['code']) {
// Hide the sign-in button now that the user is authorized, for example:
$('#signinButton').attr('style', 'display: none');
// Send the code to the server
$.ajax({
type: 'POST',
url: 'http://localhost:5000/auth_code',
contentType: 'application/octet-stream; charset=utf-8',
success: function(result) {
// Handle or verify the server response.
},
processData: false,
data: authResult['code']
}); } else {
// There was an error. } } </script> </body> </html>

Using websockets in telnet server in Python3

I have been working on a game server written in python3. My goal is to keep the communication options on it very open so that multiple different clients can easily connect. Currently all communication has been through telnet using miniboa. I would like to have the option to allow for web based clients as well. It seems like the easiest option for that would be to allow websocket connections. I have been playing around with websockify which works, however I would prefer to not use a proxy if possible because then all the connections appear to come from the proxy. Ideally what I would like is something that I can put into my telnet server to recognize a websocket handshake request (as compared to the regular requests), return the proper handshake, then keep the connection going so the commands being sent/recieved through telnet and websockets are the same. I haven't been able to find anything that allows me to do this automatically so I have been experimenting around with writing my own code to recognize a websocket handshake and reply with a corresponding handshake. I have looked at many other posts and examples, epecially python websocket handshake (RFC 6455) which I modified and converted to the following test program
#!/usr/bin/env python3
from miniboa import TelnetServer
from base64 import b64encode
from hashlib import sha1
clientlist = []
def client_connects(client):
clientlist.append(client)
def client_disconnects(client):
clientlist.remove(client)
def process_clients():
for client in clientlist:
if client.active and client.cmd_ready:
total_cmd = client.get_command()
print("incoming = {}" .format(total_cmd))
if total_cmd.find(" ") != -1: # breaking apart incoming command
cmd, cmd_var = total_cmd.split(" ", 1)
else:
cmd = total_cmd
cmd_var = ""
if cmd == "Sec-WebSocket-Key:":
GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
cmd_var = cmd_var + GUID
encoded = cmd_var.encode('utf-8')
response_key = b64encode(sha1(encoded).digest())
websocket_answer = (
'HTTP/1.1 101 Switching Protocols',
'Upgrade: websocket',
'Connection: Upgrade',
'Sec-WebSocket-Accept: {key}\r\n\r\n',
)
handshake = '\r\n'.join(websocket_answer).format(key=response_key)
client.handshakestr = handshake
if cmd == "Upgrade:":
print("Sending handshake:")
print(client.handshakestr)
print("End of Handshake")
client.send(client.handshakestr)
server = TelnetServer(port=6112, on_connect=client_connects, on_disconnect=client_disconnects)
while True:
process_clients()
server.poll()
which seems to get me past the initial handshake but then it immediately drops. From the output it looks like the browser is expecting something further but I can't figure out what. For a client I am using the following code on firefox 29.0 I downloaded from http://opiate.github.io/SimpleWebSocketServer/
<!DOCTYPE html>
<meta charset="utf-8" />
<title>WebSocket Test</title>
<script language="javascript" type="text/javascript">
function init()
{
document.myform.url.value = "ws://localhost:8000/"
document.myform.inputtext.value = "Hello World!"
document.myform.disconnectButton.disabled = true;
}
function doConnect()
{
websocket = new WebSocket(document.myform.url.value);
websocket.onopen = function(evt) { onOpen(evt) };
websocket.onclose = function(evt) { onClose(evt) };
websocket.onmessage = function(evt) { onMessage(evt) };
websocket.onerror = function(evt) { onError(evt) };
}
function onOpen(evt)
{
writeToScreen("connected\n");
document.myform.connectButton.disabled = true;
document.myform.disconnectButton.disabled = false;
}
function onClose(evt)
{
writeToScreen("disconnected\n");
document.myform.connectButton.disabled = false;
document.myform.disconnectButton.disabled = true;
}
function onMessage(evt)
{
writeToScreen("response: " + evt.data + '\n');
}
function onError(evt)
{
writeToScreen('error: ' + evt.data + '\n');
websocket.close();
document.myform.connectButton.disabled = false;
document.myform.disconnectButton.disabled = true;
}
function doSend(message)
{
writeToScreen("sent: " + message + '\n');
websocket.send(message);
}
function writeToScreen(message)
{
document.myform.outputtext.value += message
document.myform.outputtext.scrollTop = document.myform.outputtext.scrollHeight;
}
window.addEventListener("load", init, false);
function sendText() {
doSend( document.myform.inputtext.value );
}
function clearText() {
document.myform.outputtext.value = "";
}
function doDisconnect() {
websocket.close();
}
</script>
<div id="output"></div>
<form name="myform">
<p>
<textarea name="outputtext" rows="20" cols="50"></textarea>
</p>
<p>
<textarea name="inputtext" cols="50"></textarea>
</p>
<p>
<textarea name="url" cols="50"></textarea>
</p>
<p>
<input type="button" name=sendButton value="Send" onClick="sendText();">
<input type="button" name=clearButton value="Clear" onClick="clearText();">
<input type="button" name=disconnectButton value="Disconnect" onClick="doDisconnect();">
<input type="button" name=connectButton value="Connect" onClick="doConnect();">
</p>
</form>
</html>
So does anyone know either:
1. an easier way to use websockets with my telnet server?
2. what is wrong with my attempts at responding to a websocket connection?
3. if I should give up and settle for using a proxy with web connections?
Tornado has a nice compliant WebSocket handler. You can use that, or use it for reference when building yours.

HTML form data not received by Tornado class

I'm using WebSockets in the Tornado Framework and can't get the data in a html form to be sent to a tornado class.
This is my code:
class MainHandler(tornado.web.RequestHandler):
event = []
def get(self):
self.render('main.html')
def post(self):
MainHandler.event = self.get_argument('event')
When I try and send event to a WebSocketHandler class. no data is received from the form:
class WSHandler(tornado.websocket.WebSocketHandler):
def open(self):
print "tailing..."
db = Connection().blah
coll = db.blah_tail
event = MainHandler.event
print 'Filtered', event
'Filtered' just prints an empty list: "Filtered []".
The html form:
<form action="/" method="post">
<input type="text" name="event" />
<input type="submit" id="open" value="Submit Query" />
</form>
How could you send the form data to the WSHandler class?
Thanks
The js for creating the websocket:
<script>
$(document).ready(function() {
var ws;
$("#open").click(function(evt){
evt.preventDefault();
ws = new WebSocket("ws://" + "localhost" + ":" + "8888" + "/ws");
ws.onmessage = function(evt) $("#display").append(evt.data + "<br />");
ws.onclose = function(evt) {alert("Server connection terminated");};
});
});
</script>
Just like in the example from the Tornado documentation, I'll use a set for the WebSocket clients. Improving this is left as an exercise for the reader.
# clients listing on the WebSocket
clients = set()
class MainHandler(tornado.web.RequestHandler):
def get(self):
return self.render("index.html")
def post(self):
global clients
event = self.get_argument("event")
print "got event", event
if not clients:
print "No WebSockets, no point in querying the database"
return
for coordinate in self.get_coordinates(event):
for client in clients:
print "sending coordinate", coordinate, "to client", client
client.write_message(json.dumps(coordinate,
default=json_util.default))
def get_coordinates(self, event):
# replace with a real database query
for coordinate in ("No", "man's", "land"):
time.sleep(1)
yield coordinate
class WSHandler(tornado.websocket.WebSocketHandler):
def open(self):
global clients
print "WebSocket opened..."
clients.add(self)
def on_close(self):
global clients
print "WebSocket closed..."
clients.remove(self)
The relevant part of the index.html template:
<script type="text/javascript">
$(document).ready(function() {
var ws;
// open WebSocket for getting the results
ws = new WebSocket("ws://" + location.host + "/ws");
ws.onmessage = function(evt) {
$("#display").append(evt.data + "<br>");
};
ws.onclose = function(evt) {alert("Server connection terminated");};
$("#open").click(function(evt) {
evt.preventDefault();
$.post("/", $("#eventForm").serialize());
});
});
</script>
</head>
<body>
<h1>Event follower</h1>
<h2>Enter the event you would like to follow</h2>
<form id="eventForm" action="/" method="post">
<input type="text" name="event" />
<input type="submit" id="open" value="Submit Query" />
</form>
<h2>Coordinates</h2>
<div id="display">
</div>
</body>
When the page is loaded, a WebSocket connection is made to the server to the WSHandler class and the client is added to the clients set. When the page is closed, the WebSocket connection is closed and the server will remove it from the set.
When the open submit button is clicked, the form will be submitted asynchronously using AJAX to MainHandler.post. The method will find out the coordinates related to that event and send them to the listening clients as they come it. The browser receives each coordinate and it appends it to the display div.
What is the handler of your function
MainHandler or WSHandler,
Only One of them call at a single time so your syntax
event = MainHandler.event won't produce any result for you.
If your objective is only to submit the form.
Then on Submit type of event you have to write a post or get function associated with your submit call in your JS, That will work with normal tornado.web.RequestHandler on server side.
Ref. tornado web socket chat example
I have updated the chat example :
$(document).ready(function() {
if (!window.console) window.console = {};
if (!window.console.log) window.console.log = function() {};
$("#messageform").live("submit", function() {
newMessage($(this));
return false;
});
$("#message").select();
}
});
function newMessage(form) {
var message = form.formToDict();
var disabled = form.find("input[type=submit]");
disabled.disable();
$.postJSON("URL", message, function(response) {
console.log(response);
});
}
function getCookie(name) {
var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
return r ? r[1] : undefined;
}
jQuery.postJSON = function(url, args, callback) {
args._xsrf = getCookie("_xsrf");
$.ajax({url: url, data: $.param(args), dataType: "text", type: "POST",
success: function(response) {
if (callback) callback(eval("(" + response + ")"));
}, error: function(response) {
console.log("ERROR:", response)
}});
};
When you will call $("#message").submit() you will receive form data in you "URL" function
If you want's to use WSHandler then
Ref. example link will help you.
See if this helps.

Categories

Resources