Python/Flask Rest API not passing preflight w/CORS - python

I am trying to get the simplest rest api up that I can in python and I am having trouble. I'm not sure what I am doing wrong, but I think it has something to do with CORS. This is frustrating, as I have used the flask_cors package in order to fix this and it does not appear to work.
In my main.py file i have the following
from flask import Flask
from flask_cors import CORS, cross_origin
app = Flask(__name__)
CORS(app)
import routes.login
if __name__ == '__main__':
app.run(debug=True)
For my project I have this as my folder structure:
main.py
__init__.py
routes
__init__.py
login.py
And i have the following code in login.py
from flask import Flask
from flask_cors import CORS, cross_origin
from main import app
CORS(app)
#app.route('/login', methods=['POST', 'GET'])
#cross_origin()
def login(name, password):
if request.method == 'POST':
print('inside login POST')
if request.method == 'GET':
print('inside login GET')
I'm currently getting this error:
xhr.js:178 OPTIONS http://localhost:5000/login 404 (NOT FOUND)
dispatchXhrRequest # xhr.js:178
xhrAdapter # xhr.js:12
dispatchRequest # dispatchRequest.js:52
:3000/pictureswapper:1 XMLHttpRequest cannot load http://localhost:5000/login.
Response for preflight has invalid HTTP status code 404
There is some sort of CORS error, but I really don't know what's going wrong. Any ideas?
EDIT: The only place in the documentation that has anything to say about preflight is here (https://flask-cors.readthedocs.io/en/v1.3.1/index.html?highlight=preflight). If I add
#cross_origin(headers=['Content-Type']) # Send Access-Control-Allow-Headers
It doesn't break the application, but neither does it fix the error.

Revisiting this after a few months.
One of the nasty gotchas in python/flask appears to be that the compiled code will get cached, so if you change something at the entrypoint of the app (ie main.py), and don't delete the binaries that flask export creates then every time you run flask export and recompile it may be using old code!
Make sure to delete (in atom they are the purple 1/0 files -if you have file icons enabled- labeled .pyc) these files if you are getting spooky output.

Add OPTIONS to the methods keyword of your route decorator, or remove that keyword altogether.

Related

Flask routes using blueprint are not working, only '/' route is working on Ubuntu, But all is fine on Windows

I have created routes like the following in the graph.py file
bp = Blueprint('graph', __name__, url_prefix='/')
from flask import jsonify
#bp.route("/", methods=("GET", "POST"))
def index():
return render_template("graph/index.html")
#bp.route("/patent", methods=(['GET', 'POST']))
def patent():
return render_template("graph/patent.html")
#bp.route("/literature", methods=("GET", "POST"))
def literature():
return render_template("graph/literature.html")
it is working fine on my localhost(windows) but on the server(Ubuntu 18) it runs the simple route ('/') but with the name ('/patent', 'literature') it is not working.
The Error on web browser is following
Not Found
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
I have removed 3rd parameter (url_prefix='/'), and then all routes is working well for Ubuntu.
bp = Blueprint('graph', __name__)
please visit website http://18.212.192.49

Python flask URL mapping issue, returning 404

-->project
--->run.py
--->config.py
--->readme.md
--->app
--->__init__.py
--->controllers
--->__init__.py
--->test_controller.py
--->model
--->__init__.py
--->test_model1.py
--->test_model2.py
run.py
from app import app
app.run(host = '0.0.0.0', port = 8080, debug = True)
config.py - All configuration variable
app/__init__.py
from flask import Flask
app = Flask(__name__)
controllers/__init__.py - Empty
controllers/test_controller.py
#app.route('/test', methods=['POST'])
def test():
return "Hello world"
When I start my server form run.py the server gets started.
But when I try the URL http://locahost:8080/test, it returns 404.
But if the route is configured in app/___init__.py it is working.
Can anyone please guide me what is incorrect here in configuration.
I want to keep the above structure, please let me know of any issues.
Unless you import the file containing the #app.route decorator, it won't be registered. Flask won't import and register all .py files automagically for you.
At the end of your __init__.py file in app/, import projectname.controllers, and import test_controller in the __init__.py file in the controllers module.

I can't go to the other paths i am using flask

I am studying this course on flask. This is the basic flask code. When I am on the first route I am fine but when I try to put slash and got for another page it doesn't work.
I get this message:
"The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again."
I did run FLASK_APP=app.py flask run
after saving.
from Flask import flask
app= Flask(__name__)
#app.route('/')
def index():
return "index"
#app.route('/me')
def me():
return "me"
if __name__== "__main__":
app.run(debug=True)
In class it works well. When i do it it does not
127.0.0.1 - - [08/Jul/2019 02:43:55] "GET /me/ HTTP/1.1" 404 -
I'm guessing 404 at the end is problem
After the reply
from Flask import flask
app= Flask(__name__)
strict_slashes=False
#app.route('/')
def index():
return "index"
#app.route('/me/')
def me():
return "me"
if __name__== "__main__":
app.run(debug=True)
You have declared your "/me" route explicitly without trailing slash. However, when calling the URL, you are calling it with slash in the end "/me/". Werkzeug (Flask development application server) by default has the rule of "strict_slashes=True", which requires you to follow exact route declaration when calling your URLs. In other words, if in your code, you declared "#app.route('/me'), your should call "127.0.0.1/me", not "127.0.0.1/me/".
Removing the slash in the end (e.g. http://localhost/me) will fix your issue. You can also change the Werkzeug setting and set strict_slashes=False if you want to remove the default rule.
I would say make a app.errorhandler(404) and then define what to do after you get an error to check if it is a 404 error, and other errors. I would also say use html and make links which you can use to go into different pages, it is easier than typing manually. here is my code:
python:
from flask import Flask, render_template
app = Flask(__name__)
app.route('/')
def home():
return render_template('home.html')
app.route('/me')
def me():
return 'me'
app.errorhandler(404)
def error(arg):
return 'wrong url'
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8080)
html:
<!-- you can use css to make the link look better or <style> </style>-->

How to obtain values of parameters of get request in flask?

The answer that I found on the web is to use request.args.get. However, I cannot manage it to work. I have the following simple example:
from flask import Flask
app = Flask(__name__)
#app.route("/hello")
def hello():
print request.args['x']
return "Hello World!"
if __name__ == "__main__":
app.run()
I go to the 127.0.0.1:5000/hello?x=2 in my browser and as a result I get:
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.
What am I doing wrong?
The simple answer is you have not imported the request global object from the flask package.
from flask import Flask, request
This is easy to determine yourself by running the development server in debug mode by doing
app.run(debug=True)
This will give you a stacktrace including:
print request.args['x']
NameError: global name 'request' is not defined
http://localhost:5000/api/iterators/opel/next?n=5
For something like the case before
from flask import Flask, request
n = request.args.get("n")
Can do the trick

Changing URLs after deploying Flask app

So, I have a flask application that works well when it's not deployed. Imagine it has pages for /index/ and /home/ and /home/field/. Now that I have deployed the app using Apache and mod_wsgi, it needs to have a prefix for every URL.
Now, it should look like /newapp/index/ and /newapp/home/ and /newapp/home/field/.
So, I changed all of the URLs to include the new /newapp/ prefix, but the only URL that works with it is the original /index/ URL. All of the others return a
Not Found The requested URL was not found on the server.
in the browser when I click for that URL. I definitely handle that route in my main.py, so I don't know why it would not be found.
Anyone know what is going on?
EDIT: adding some code
Basically I changed all my code in main.py from:
Original:
#app.route('/')
#app.route('/index/', methods=['GET', 'POST'])
def index():
#Stuff
#app.route('/home/')
def farms():
#More stuff
#app.route('/home/<selector>')
def fields(selector):
#Further stuff
To....
New Code
#app.route('/newapp/')
#app.route('/newapp/index/', methods=['GET', 'POST'])
def index():
#Stuff
#app.route('/newapp/home/')
def farms():
#More stuff
#app.route('/newapp/home/<selector>')
def fields(selector):
#Further stuff
I did this because the domain I am using already has another Flask app, so I had to differentiate between the two. Also, I expect there to be more flask apps in the future, so this newapp will end up being an identifier for any given flask app.
I changed main.py as well has all of my hrefs in my templates. So, the hrefs went from
href=/index/
to
href=/newapp/index/
And, I get the error that I posted above whenever I try to click on a link
Further info:
So, checking out the apache error logs one error says, File does not exist: /var/www/flask_util.js, because in my main.py I call from flask_util_js import FlaskUtilJs. I'm not sure if this has anything to do with the URL routing, but it might
You don't need to add the prefix in your code.
Say you have code like
#app.route('/hi', methods = ['GET','POST'])
def myIndex():
return "Hello World!", 200
And you set your alias like to deploy it to www.myserver.com/app/
WSGIScriptAlias /app /var/www/myDir/myApp/app.wsgi
the server should automatically map www.myserver.com/app/hi to /hi in your application.
However if you set the mapping to
#app.route('/newapp/hi', methods = ['GET','POST'])
def myIndex():
return "Hello World!", 200
You WSGI app would only receive the call for /hi (server strips away the prefix) so it would find no matching Path and return not found.

Categories