Flask routing not working - python

It's the most basic thing to ask but #app.route('/') is not working on my Linux server.
Below is the code :
from flask import Flask, jsonify, request
from app import models
import json
import time
app = Flask(__name__)
app.url_map.strict_slashes = True
#app.route('/')
def blank():
return 'Hello ABC!'
#app.route('/driftking')
def blank2():
return 'Hello driftking!'
# dynamic route
#app.route("/test/<search_query>")
def search(search_query):
return search_query
#app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
return "POST METHOD"
elif request.method == 'GET':
return "GET REQUEST ARE NOT ALLOWED"
if __name__ == '__main__':
app.run(debug=True)
app.run()
Very basic app, all's working fine on local machine but not on my linux server.
E.g. if I load http://xxx.xxx.xxx.xxx/projectname ---- it shows Hello ABC!
If I load http://xxx.xxx.xxx.xxx/projectname/driftking -- it redirects me to http://xxx.xxx.xxx.xxx ( i.e my server's homepage)
If I load http://xxx.xxx.xxx.xxx/projectname/test/search -- 404 error not found
If I load http://xxx.xxx.xxx.xxx/projectname/login -- it redirects me to http://xxx.xxx.xxx.xxx ( i.e my server's homepage)
127.0.0.1 - - [24/Nov/2017 19:37:01] "POST //login HTTP/1.1" 405 -
^^This is what I get on terminal. I don't understand why I get two leading slashes everytime.
But If do http://xxx.xxx.xxx.xxx/projectname/insert-any-word/login , my post req get's executed. At the same time on local machine i dont get two leading slashes // to the path and thus the request get's processed.

There are a couple of things wrong but try this, you'll need a proxy to help with the rerouting.
from flask import Flask, jsonify, request
from app import models
import json
import time
from werkzeug.contrib.fixers import ProxyFix
app = Flask(__name__)
app.wsgi_app = ProxyFix(app.wsgi_app)
app.url_map.strict_slashes = False
#app.route('/')
def blank():
return 'Hello ABC!'
#app.route('/driftking')
def blank2():
return 'Hello driftking!'
# dynamic route
#app.route("/test/<search_query>")
def search(search_query):
return search_query
#app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
return "POST METHOD"
elif request.method == 'GET':
return "GET REQUEST ARE NOT ALLOWED"
if __name__ == '__main__':
app.run(debug=True)

Related

giving error the request url was not found on your server

i am getting error 404 while running this
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again. how do i need to run the server ? please help
from flask import Flask
from flask import render_template
from flask import request
app = Flask(__name__, template_folder="templates/")
app.route("/login", method=['POST', 'GET'])
def index():
greeting = "Hello World"
if request.method == "POST":
name = request.form['name']
greet = request.form['greet']
greeting = f"{greet}, {name}"
return render_template("index.html", greeting=greeting)
else:`enter code here`
return render_template("hello_form.html")
if __name__ == "__main__":
app.run(debug=True)
You need to replace
app.route("/login", method=['POST', 'GET'])
By
#app.route("/login", methods=['POST', 'GET'])
Edit: also, methods

Flask Print Not Working

If I send run this program to do a HTTP Post to my Flask server, which I know returns a 200 response:
import requests
import json
dump= '{"on": false}'
r = requests.post('http://127.0.0.1:5000', data=dump,
headers={'Content-Type': 'application/json'})
And my Flask server's code:
from flask import Flask
from flask import request, jsonify
import requests
app = Flask(__name__)
#app.route('/', methods=['GET', 'POST'])
def signal():
if request.method == 'POST':
content = request.get_json()
return jsonify(content)
print(jsonify(content))
r = requests.put("http://192.168.1.102/api/F5La7UpN6XueJZUts1QdyBBbIU8dEvaT1EZs1Ut0/lights/5/state/", jsonify(content))
else:
return 'Hello, world!'
if __name__ == '__main__':
app.run(debug=True)
I want to print the data to the console, then send it over to a bridge on the network using a HTTP PUT. Neither of these are working, and I'm not sure why.
You need to return at the very end of the function
#app.route('/', methods=['GET', 'POST'])
def signal():
if request.method == 'POST':
content = request.get_json()
print(content)
r = requests.put("http://192.168.1.102/api/F5La7UpN6XueJZUts1QdyBBbIU8dEvaT1EZs1Ut0/lights/5/state/", content)
return jsonify(content)
else:
return 'Hello, world!'
Note: You probably are over-using the jsonify function because the jsonify() function in flask returns flask.Response() object, and not a JSON string that you would POST or PUT to another service.

Register new module as a REST API in python-flask dynamically

Consider I have this following code:
from flask import Flask
from flask import request
app = Flask(__name__)
#app.route('/test', methods=['GET'])
def get():
if request.method == 'GET':
return 'hello'
#app.route('/post', methods=['POST'])
def post():
if request.method == 'POST':
name = request.form['name']
return name
if __name__ == '__main__':
app.run()
I run the code and the server starts with these two API endpoints.
Now, I want to register one more endpoint in the same flask app without restarting the currently server, so that any transactions going on the existing endpoints are not interrupted.
Is there a way I can register a new endpoint with closing/restarting the server on the same flask app?
You can register new rules at any point in your code using Flasks add_url_rule() function. This function is actually called by the route() decorator as well.
#app.route('/')
def index():
pass
Is equivalent to:
def index():
pass
app.add_url_rule('/', 'index', index)

How to print output using only a POST Method?

How can I print something like this:
{
username = admin
email = admin#localhost
id=42
}
With only using a method = ['POST'] and without using render_template?
PS: I already made it run with ['GET']
Here's my code:
from flask import Flask, jsonify, request
app = Flask(__name__)
#app.route('/', methods=['POST'])
def index():
if request.method == 'POST':
return jsonify(username="admin",
email="admin#localhost",
id="42")
else:
if request.method == 'POST':
return jsonify(username="admin",
email="admin#localhost",
id="42")
if __name__ == "__main__":
app.run()
And what I get is a 405 Method error.
Hey make sure your trailing stashes in your html are correct.
you may refer to : Flask - POST Error 405 Method Not Allowed and flask documentation : http://flask.pocoo.org/docs/0.10/quickstart/
this
<form action="/" method="post">
and this is same same but different
<form action="" method="post">
Accessing it without a trailing slash will cause Flask to redirect to the canonical URL with the trailing slash.
Given your error 405, I am suspecting that this is your problem. GET is fine, because you will just be redirected.
Try returning the form (as biobirdman said) on a GET request. Not sure why you need the request.method == 'POST' conditional statement. The parameter methods=['POST'] in the route should suffice.
Try this:
from flask import Flask, jsonify, request
app = Flask(__name__)
#app.route('/', methods=['POST'])
def index():
return jsonify(username="admin", email="admin#localhost", id="42")
#app.route('/', methods=['GET'])
def form():
return "<form action='/' method='POST'>" \
"<input type='submit'>" \
"</form>"
if __name__ == "__main__":
app.run()

Flask-login with static user always yielding 401- Unauthorized

I am trying to build a super simple web app for my own use. I'll be the only user, so I don't feel the need to involve a database for user management. I'm trying to use flask-login, but even though my call to login_user succeeds, I'm still met with a 401-Unauthorized page after the redirect to a page with #login_required. Here is the entirety of my app:
from flask import Flask, render_template, request, flash, redirect, url_for
from flask.ext.login import LoginManager, login_user, logout_user, current_user, login_required, UserMixin
app = Flask(__name__, static_url_path="")
app.secret_key = "[redacted]"
login_manager = LoginManager()
login_manager.init_app(app)
#login_manager.login_view = "login"
class User(UserMixin):
def __init__(self, id):
self.id = id
nathan = User('nathan')
#login_manager.user_loader
def load_user(userid):
if userid == 'nathan':
return nathan
else:
return None
#app.route("/logout")
#login_required
def logout():
logout_user()
return redirect(url_for('login'))
#app.route('/')
#login_required
def index():
return render_template('index.html')
#app.route("/login", methods=["GET", "POST"])
def login():
if request.method == 'POST':
if request.form['username'] == 'nathan'\
and request.form['password'] == '[redacted]':
login_user(nathan, remember=True)
flash('logged in...', 'success')
return redirect(request.args.get("next") or url_for("index"))
else:
flash('Incorrect username or password. Try again.', 'error')
return render_template("login.html");
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
I've verified that the login actually succeeds (login_user returns true) and that load_user is returning the nathan object.
[EDIT] Also, I'm currently using the Flask development server, in case that's relevant.
Not sure where I'm going wrong. Thanks in advance!
Update:
Since a newer version(0.2.2) of Flask-Login this is no more an issue. Check out the changes in this commit.
If you are using an older version, read on.
The problem here is static_url_path="". For Flask-Login to work you can not have an empty string static_url_path.
The following lines in the Flask-Login source(older version) reveal this:
if (current_app.static_url_path is not None and
request.path.startswith(current_app.static_url_path)
):
# load up an anonymous user for static pages
_request_ctx_stack.top.user = self.anonymous_user()
return
Since your static_url_path is "" the if condition evaluates to True, because of which every page you visit acts like a static page, and hence Flask-Login always loads an anonymous user, instead of continuing to load the actual user(using the load_user callback).
Also do not forget to uncomment #login_manager.login_view = "login"
If you still want to use the root folder of the app itself as the static folder, take a look at this solution, using SharedDataMiddleWare:
app.debug = True
if app.config['DEBUG']:
from werkzeug import SharedDataMiddleware
import os
app.wsgi_app = SharedDataMiddleware(app.wsgi_app, {
'/': os.path.dirname(__file__)
})
if __name__ == "__main__":
app.run(host="0.0.0.0")

Categories