How to access Flask Request header outside route method - python

I want to access headers for a certain API calls outside of its api route. I tried using the app_context and test_request_context but it doesn't seem to work.
from flask import Flask, request
app = Flask("app")
def access_header_for_something():
with app.test_request_context():
with app.app_context():
print(request.headers.get("Authorization"), request.host, request.path)
#app.route('/')
def index():
access_header_for_something()
return 'hello'
if __name__=="__main__":
app.run(debug=True)
Any suggestions would be really helpful

The above code snippet work with slight tweak:
from flask import Flask, request
app = Flask("app")
def access_header_for_something():
with app.app_context():
print(request.headers.get("Authorization"), request.host, request.path)
#app.route('/')
def index():
access_header_for_something()
return 'hello'
if __name__=="__main__":
app.run(debug=True)

Related

How to create first_or_redirect() like first_or_404() in flask application

I have a flask app with flask login. I want to protect one user from accessing another user's data.
This returns error, which is fine, but I would like to have a redirect to home instead.
#login_required
def myurl(po_id):
current_po = Purchaseorder.query.filter_by(id=po_id, owner=current_user.id)\
.first_or_404()
# delete edit ..
I tried also:
#login_required
def myurl(po_id):
current_po = Purchaseorder.query.filter_by(id=po_id).first()
if current_po.owner!=current_user.id:
redirect ...
But seems too much writing every time.
Is there a solution for that and maybe also for .all() ?
You can easily write your own decorator and control if user was authorized or not:
from functools import wraps
from flask import Flask, redirect, url_for, session
app = Flask(__name__)
app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'
def wrapper_redirect(f):
#wraps(f)
def wrapped_func(*args, **kwargs):
if not session.get("login"):
return redirect(url_for("index"))
else:
return f(*args, **kwargs)
return wrapped_func
#app.route("/")
def index():
session["login"] = True # log in
return "<h1>index page</h1>"
#app.route("/test")
#wrapper_redirect
def hello_world():
if session.get("login"):
del session["login"] # log out
return "<p>Hello, World!</p>"
if __name__ == '__main__':
app.run(host="0.0.0.0", port=9999)

"NameError: name 'redirect' is not defined" even though redirect is imported

I have this simple Flask 1.1.x app:
from flask import Flask
from flask import redirect, render_template, url_for
app = Flask(__name__)
#app.route('/', methods=['GET'])
def index():
return render_template("index.html")
#app.route('/donate', methods=['GET'])
def donate():
return render_template("donate.html")
#app.route('/donations', methods=['GET'])
def donations():
return redirect(url_for('donate'))
if __name__ == '__main__':
app.run(host='localhost', port=8080, debug=True)
I'm developing on a local server. When I attempt to access /donations in a browser, I get an Internal Server Error and the local server reports this error:
ERROR in app: Exception on /donations [GET]
<trimmed>
return redirect(url_for('donate'))
NameError: name 'redirect' is not defined
I don't understand why it's reporting redirect as undefined, since I am importing it and I'm calling it the same way the Flack Quickstart Guide does.
Could you replace return redirect(url_for('donate')) with return redirect('/donate') ?

Is there a way to pass HTML code in flask as string?

Is there a way to pass HTML code as a string in python/flask rather than render template HTML file in a directory?
for example
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/')
def home():
return render_template('index.html') # Instead of giving file path I want to pass HTML code directly
if __name__ == '__main__':
app.run()
I guess you mean something like this:
from flask import Flask
app = Flask(__name__)
HTML_AS_TEXT = """<p>hello world</p>"""
#app.route('/')
def home():
return HTML_AS_TEXT
if __name__ == '__main__':
app.run()

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)

Rewrite a URL with Flask

Is it possible to rewrite a URL with Flask e.g. if a POST request is received via this route:
#app.route('/', methods=['GET','POST'])
def main():
if request.method == 'POST':
#TODO: rewrite url to something like '/message'
return render_template('message.html')
else:
return render_template('index.html')
I'm aware I can use a redirect and setup another route but I prefer to simply modify the url if possible.
You can call your route endpoint functions from another routes:
# The “target” route:
#route('/foo')
def foo():
return render_template(...)
# The rewrited route:
#route('/bar')
def bar():
return foo()
You can even access g etc. This approach can be also used when the Flask's routing facilities cannot do something that you want to implement.
This is actual solution to this problem (but maybe a dirty hack):
def rewrite(url):
view_func, view_args = app.create_url_adapter(request).match(url)
return app.view_functions[view_func](**view_args)
We invoke the URL dispatcher and call the view function.
Usage:
#app.route('/bar')
def the_rewritten_one():
return rewrite('/foo')
I think you could be interested in redirect behavior
from flask import Flask,redirect
then use
redirect("http://www.example.com", code=302)
see: Redirecting to URL in Flask
from flask import Flask, redirect, url_for
app = Flask(__name__)
#app.route("/")
def home():
return "hello"
#app.route("/admin"):
def admin():
return redirect(url_for("#name of function for page you want to go to"))

Categories