Flask 404 for POST request - json

I am very new to Flask. Trying to build a flask app which fetches data from the backend neo4j and posts it in JSON format. The eventual aim is to do visualisation using d3.js . But for starters, I want to post it as JSON.
Below is my views.py:
import models
from models import Customer
from flask import Flask, request, session, redirect, url_for, render_template, flash,json,jsonify
import os
app = Flask(__name__)
#app.route('/',methods = ['GET','POST'])
def enter_ID():
if request.method == 'POST':
Galactic_ID = request.form['Galactic_ID']
if Customer(Galactic_ID).find():
return redirect(url_for('Customer_relationships',Galactic_ID=request.form.get('Galactic_ID')))
else:
return "Wrong Galactic_ID"
else:
return render_template('Gal.html')
#app.route('/Customer_relationships/<Galactic_ID>')
def Customer_relationships(Galactic_ID):
data = Customer(Galactic_ID).get_relationships():
return render_template('rel.html',Galactic_ID=Galactic_ID,data =json.dumps(data))
if __name__ == '__main__':
host = os.getenv('IP','0.0.0.0')
port = int(os.getenv('PORT',5000))
app.secret_key = os.urandom(24)
app.run(host=host,port=port)
In views.py , Customer(Galactic_ID).find() and Customer(Galactic_ID).get_relationships() call the functions find(self) and get_relationships(self) under Customer class in models.py :
When I try and run this below are the HTTP Calls:
127.0.0.1 - - [29/Jul/2016 17:54:53] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [29/Jul/2016 17:54:56] "POST / HTTP/1.1" 302 -
127.0.0.1 - - [29/Jul/2016 17:54:56] "GET /Customer_relationships/2000000000084001287 HTTP/1.1" 200 -
127.0.0.1 - - [29/Jul/2016 17:54:56] "POST /Customer_relationships HTTP/1.1" 404 -

Below is the working solution:
import models
from models import Customer
from flask import Flask, request, session, redirect, url_for, render_template, flash,json,jsonify
import os
app = Flask(__name__)
#app.route('/',methods = ['GET','POST'])
def enter_ID():
if request.method == 'POST':
Galactic_ID = request.form['Galactic_ID']
if Customer(Galactic_ID).find():
return redirect(url_for('relationships',ID=request.form.get('Galactic_ID')))
else:
return "Wrong Galactic_ID"
else:
return render_template('Gal.html')
#app.route('/Customer_relationships',defaults={'ID':'Galactic_ID'},methods=['GET','POST'])
#app.route('/Customer_relationships/<ID>',methods=['GET','POST'])
def relationships(ID):
data = Customer(ID).get_relationships()
return render_template('rel.html',data= json.dumps(data))
if __name__ == '__main__':
host = os.getenv('IP','0.0.0.0')
port = int(os.getenv('PORT',5000))
app.secret_key = os.urandom(24)
app.run(host=host,port=port)

I had a similar issue that was fixed with the flask-cors module.
First it needs to be installed in the terminal $ pip install flask-cors
Then added to your app:
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
#app.route("/", methods=['POST'])
def helloWorld():
return "Hello, cross-origin-world!"

Related

pass SQL query in POST request using Flask

I want to pass a SQL query as parameter in a POST request. Ideally this SQL query will be further passed into MySQL connection, and then it can fetch data back.
Here is what I did:
These are basic modules and settings:
from flask import Flask
from flask_cors import CORS, cross_origin
app = Flask(__name__)
CORS(app)
from app import app
from flaskext.mysql import MySQL
mysql = MySQL()
app.config['MYSQL_DATABASE_USER'] = 'root'
app.config['MYSQL_DATABASE_PASSWORD'] = 'root'
app.config['MYSQL_DATABASE_DB'] = 'hibernate1'
app.config['MYSQL_DATABASE_HOST'] = 'localhost'
mysql.init_app(app)
This is the main.py, where I want to pass a SQL query:
from urllib import response
import pymysql
from app import app
from config import mysql
from flask import jsonify
from flask import flash, request
#app.route('/SQL/<query>', methods=['POST'])
def return_query(query):
conn = mysql.connect()
cursor = conn.cursor(pymysql.cursors.DictCursor)
cursor.execute(query)
Rows = cursor.fetchall()
respone = jsonify(Rows)
return respone
if __name__ == "__main__":
app.run()
This is test.py:
import requests
dictToSend = {"query": "select * from student"}
res = requests.post('http://localhost:5000/SQL', json = dictToSend)
print ('response from server:', res.text)
dictFromServer = res.json()
print(dictFromServer)
However, I got the following errors:
response from server: <!doctype html>
<html lang=en>
<title>404 Not Found</title>
<h1>Not Found</h1>
<p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p>
It says the requested URL was not found. But the following GET request works fine:
#app.route('/', methods=['GET'])
def return_hello():
return {"data": "hello"}
Could anyone tell me what I missed in the POST request? Thanks.

POST request TypeError with PyMongo on Postman

Here's my code so far:
from flask import Flask, request, jsonify
from flask_pymongo import PyMongo, ObjectId
from flask_cors import CORS
import pymongo
app = Flask(__name__)
app.config["MONGO_URI"]="mongodb+srv://<USER>:<PASSWORD>...etc"
mongo = PyMongo(app)
CORS(app)
db = mongo.db.users
#app.route('/users', methods=['GET', 'POST'])
def createUser():
if request.method == "GET":
return jsonify({'msg': 'Successful GET response'})
elif request.method == "POST":
id = db.insert_one({
'username': request.json['username'],
'firstName': request.json['firstName'],
'lastName': request.json['lastName'],
'dob': request.json['dob']
})
return jsonify({'id': str(ObjectId(id)), 'msg': 'User Added Successfully!'})
#run app
if __name__ == "__main__":
app.run(debug=True)
When I attempt a POST request on Postman at the url "/users" it gives me the following 500 Error response:
TypeError: id must be an instance of (bytes, str, ObjectId), not <class 'pymongo.results.InsertOneResult'>
I'm following a tutorial that uses .insert() instead of the newer .insert_one() or .insert_many(), I wonder if this has any relation to the issue.
Any help is appreciated!
I got it. All I had to do was switch
return jsonify({'id': str(ObjectId(id)), 'msg': 'User Added Successfully!'})
to
return jsonify({'id': str(id.inserted_id), 'msg': 'User Added Successfully!'})
Postman response:
{
"id": "6[...]b",
"msg": "User Added Successfully!"
}

WebSocket connection failed: Error during WebSocket handshake: Unexpected response code: 200

I have Flask application and I want to use flask-socketio to handle webosockets with gunicorn and eventlets.
Although, when I try to connect my test client (http://www.websocket.org/echo.html) I am receiving:
WebSocket connection to 'ws://localhost/socket.io?encoding=text' failed: Error during WebSocket handshake: Unexpected response code: 200
socketio_app.py
from flask import Flask, render_template
from flask_socketio import SocketIO
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app, port=9090, host='0.0.0.0', async_mode='eventlet', debug=True)
#app.route('/socket.io')
def index():
return render_template('index.html')
if __name__ == '__main__':
socketio.run(app)
and I run it in this way:
gunicorn -k eventlet -w 1 socketio_app:app -b 0.0.0.0:9090 --error-logfile - --access-logfile - --log-level debug
Should I use it in another way? Should I manually modify my response like that?
#app.route('/socket.io')
def index():
return Response(status=101, headers={
'Connection': 'Upgrade',
'Upgrade': 'websocket'
})
You are using a WebSocket client to connect to a Socket.IO server. Use a Socket.IO client and you will be fine. WebSocket is not the same as Socket.IO, the latter is implemented on top of WebSocket and uses a different protocol.

flask integration with mysqldb

I am new to flask framework. I want to connect with a MySQL database
and my code in the __init__.py is
app = Flask(__name__)
app.config.from_object(Config)
db = SQLAlchemy(app)
migrate =Migrate(app,db)
but I am getting this error
Authentication plugin '{0}' is not supported".format(plugin_name))
sqlalchemy.exc.NotSupportedError:
(mysql.connector.errors.NotSupportedError) Authentication plugin
'caching_sha2_password' is not supported
(Background on this error at: http://sqlalche.me/e/tw8g)
Can anyone please help me?
Please install the following requirement using pip:
pip install flask-mysql
I perform my MySQL connection with Flask using similar code (tested now):
from flask import Flask
from flaskext.mysql import MySQL
app = Flask(__name__)
app.config['MYSQL_DATABASE_USER'] = 'youruser'
app.config['MYSQL_DATABASE_PASSWORD'] = 'yourpassword'
app.config['MYSQL_DATABASE_DB'] = 'yourdb'
app.config['MYSQL_DATABASE_HOST'] = 'yourhost'
mysql = MySQL(app)
mysql.init_app(app)
#app.route("/")
def hello_db():
conn = mysql.connect()
cursor =conn.cursor()
cursor.execute('''SELECT * from yourtable''')
data = cursor.fetchall()
return str(data)
if __name__ == "__main__":
app.run()
Please change the variables with your data (user/password etc) and try the connection.

running API in python on localhost

I need to POST a JSON from a client to a server. I have written two simple files as client and server to run them on localhost. Running the second program on http://127.0.0.1:5000/a, I have this output:
[
{
"origin_lat": 38.916228,
"origin_lon": -77.031576
}
]
I want to have the same output using POST request by running the first program on http://127.0.0.1:5001/b. It doesn't run and gives me this error:
Internal Server Error
The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.
I am running them on Anaconda.
First program:
from flask import Flask, jsonify
import requests
data=[]
data.append({"origin_lat":38.916228,"origin_lon":-77.031576})
app = Flask(__name__)
#app.route("/b")
def home():
res = requests.post("http://127.0.0.1:5000/a", json=data)
dictFromServer = res.json()
return jsonify(dictFromServer)
if __name__ == "__main__":
app.run(port=5001,threaded=True)
Second program:
from flask import Flask, jsonify
app = Flask(__name__)
#app.route("/a")
def post_api_fun_single_time():
data=[]
data.append({"origin_lat":38.916228,"origin_lon":-77.031576})
return jsonify(data)
if __name__ == "__main__":
app.run(port=5000,threaded=True)
I solved it myself. The problem was that I was looking to run it using the browser. It can work if we test it by "Advanced REST client".