How to add headers to all routes in flask? - flask

I want to add header "Access-Control-Allow-Origin: *" to all routes in flask. How can I do?
I tried to use flask_cors.CORS(app), but it didn't work.
I am not a native English speaker, so pleace forgive me for my bad English

Try using this code
from flask_cors import CORS, cross_origin
# import those packages you have already imported
CORS(app, support_credentials=True)
#app.route('/', methods = ['GET', 'POST'])
#cross_origin(supports_credentials=True)
def index():
return render_template('sample.html')
If not works then do let me know... will figure it out

Try this:
First import make response:
from flask import make_response
Then this:
#app.route('/', methods = ['GET', 'POST'])
def index():
r = make_response(render_template('index.html'))
r.headers.set('Access-Control-Allow-Origin', "*")
return r

This works for me
flask_cors.CORS(app, support_credentials=True)
#app.route('/', methods = ['GET', 'POST'])
#cross_origin(supports_credentials=True)
def home():
return render_template('index.html')

Related

python Flask redirect(url_for()) not working

i'm making a sign up page in flask but when i press submit it doesn't redirect to the home page
from flask import Flask, redirect, url_for, render_template, request
app = Flask(__name__)
#app.route('/', methods = ['GET', 'POST'])
def login():
if request == 'POST':
input1 = request.form.get("input1")
input2 = request.form.get("input2")
return redirect(url_for("home"))
return render_template('lo.html')
#app.route('/home', methods = ['GET','POST'])
def home():
return render_template('ho.html')
if __name__ == "__main__":
app.run(debug=True)
i have no idea why it doesn't work can someone help me?
Did you visit the “/“ path in browser? That’s “GET” method, not match your “POST” method. In addition, you should use if request.method == 'POST': to check the request method in flask.
Try to remove the condition, it may work as you expected.

How to integrate webargs + marshmallow?

I am only beginner in flask. Trying to integrate marshmallow and webargs. It perfectly works in flask-restful Resource class. But when I use a simple flask route it does not work
routes.py
class UserAPI(Resource):
#use_args(UserSchema())
def post(self, *args):
print(args)
return 'success', 201
def get(self):
return '<h1>Hello</h1>'
#bp.route('/test/', methods=['POST'])
#use_kwargs(UserSchema())
def test2(*args, **kwargs):
print(args)
print(kwargs)
return 'success', 201
api.add_resource(UserAPI, '/', endpoint='user')
I've added error handler which is necessary when using use_args
from webargs.flaskparser import parser, abort
from webargs import core
#parser.error_handler
def webargs_validation_handler(error, req, schema, *, error_status_code, error_headers):
status_code = error_status_code or core.DEFAULT_VALIDATION_STATUS
abort(
400,
exc=error,
messages=error.messages,
)
That's what I'm getting when I make request to Resource endpoint what is normal
And that's what I'm getting when I make request to a simple flask route what is not normal
I want to be able to use both ways
Found answer in webargs docs :)
https://webargs.readthedocs.io/en/latest/framework_support.html#error-handling
from flask import jsonify
# Return validation errors as JSON
#app.errorhandler(422)
#app.errorhandler(400)
def handle_error(err):
headers = err.data.get("headers", None)
messages = err.data.get("messages", ["Invalid request."])
if headers:
return jsonify({"errors": messages}), err.code, headers
else:
return jsonify({"errors": messages}), err.code

Flask unittesting API requests

I am trying to write unit test cases for flas api server.
Can someeone please suggest ow to get rid of auth.login_required.
Tried mocking auth, but of no use.
with test_client its not hitting code block too.
api.py
from flask import Flask
from flask.ext.httpauth import HTTPBasicAuth
app = Flask(__name__)
auth = HTTPBasicAuth()
#app.route('/')
#auth.login_required
def index():
print "In index"
response.status_code = 200
return response
Tried following http://flask.pocoo.org/docs/0.12/testing/
from src.api import app
from unittest import TestCase
class TestIntegrations(TestCase):
def setUp(self):
self.app = app.test_client()
def test_thing(self):
response = self.app.get('/')
Can someone please help ??
There are two ways to do so - first is to disable authorization in tests:
// in your test module
from api import app, auth
import unittest
#auth.verify_password
def verify_password(user, password):
"""Overwrite password check to always pass.
This works even if we send no auth data."""
return True
Another approach is to actually send the auth headers from tests (this way you can also test your authorization system):
from api import app
from base64 import b64encode
import unittest
class ApiClient:
"""Performs API requests."""
def __init__(self, app):
self.client = app.test_client()
def get(self, url, **kwargs):
"""Sends GET request and returns the response."""
return self.client.get(url, headers=self.request_headers(), **kwargs)
def request_headers(self):
"""Returns API request headers."""
auth = '{0}:{1}'.format('user', 'secret')
return {
'Accept': 'application/json',
'Authorization': 'Basic {encoded_login}'.format(
encoded_login=b64encode(auth.encode('utf-8')).decode('utf-8')
)
}
class TestIntegrations(unittest.TestCase):
def setUp(self):
self.app = ApiClient(app)
def test_thing(self):
response = self.app.get('/')
print(response.data)
The ApiClient helper can also define post, delete methods which will be similar to get.
The full source code with examples is here.

Django : how to include a view.py file inside a view from another app?

I've made a "paginator" app, that add such SEO optimisation for all my pages.
So I need to pass all visible page url through paginator.view
But, I want to keep my apps as structured as possible.
For an example here is a view for my gallery app:
gallery.views
from django.shortcuts import render
from gallery.models import GalleryItem
def home(request):
img_to_display = GalleryItem.objects.filter(published=True
).order_by('-date')
return render(request, 'gallery/all.html', locals())
...
Now I'm doing like that form my view in paginator :
My current paginator.views
from django.shortcuts import render, get_object_or_404, redirect
from gallery.models import GalleryItem
from paginator.models import Page
import gallery
def custom_page(request, url):
current_page = url
# just for the gallery page :
if url == 'gallery':
img_to_display = GalleryItem.objects.filter(published=True
).order_by('-date')
# for all my page
page_to_load = get_object_or_404(Page, name=url)
template_to_load = "paginator/" + page_to_load.template_name
return render(request, template_to_load, locals())
So I copy/paste my view and all dependencies, but that is really ugly, and not at all DRY, worth it's not maintainable. I try something like that but it doesn't work :
paginator.views : option1
from django.shortcuts import render
import gallery
def custom_page(request, url):
if url == 'gallery':
gallery.views.home(request)
if url == 'anotherpage':
anotherapp.views.home(request)
...
Or something like that :
paginator.views : option 2
from django.shortcuts import render
def custom_page(request, url):
if url == 'gallery':
include("gallery.views.py")
if url == 'anotherpage':
include("anotherapp.views.py")
...
Note: I prefer the last style option because it minimize the import at the start of the paginator.views file.
Thanks a lot for helping ! :)
If you need a mechanism which is executed before the request is dispatched to a view, I would recommend using a middleware class. You can read more about it in the Django docs.
Another option is to use class based views to create a SEOView which can be inherited by every custom page view of yours. Some example of how it could look like:
from django.views.generic.base import View
class MySeoView(View):
def dispatch(self, request, *args, **kwargs):
# some logic for SEO
return super().dispatch(request, *args, **kwargs)
class CustomView1(MySeoView):
def get(self, request, *args, **kwargs):
# do normal stuff for this page
return HttpResponse(...)
def post(self, request, *args, **kwargs):
# maybe some other logic for posts
return HttpResponse(...)
To come back to your own options:
If you want to make #1 work, I guess you have to return the result of the view:
...
if url == 'someUrl':
return gallery.views.home(request)
...
Firstly I want to thanks Gocht to have sended me on a good way. So that's what I've done :
paginator.views
def custom_page(request, url):
"""
Vue d'une page statique.
"""
if url == 'gallery':
import gallery
gal = gallery.views.render_gallery(request)
gal.render()
gallery_html = gal.rendered_content
if url == 'xxx':
...
page_to_load = get_object_or_404(Page, url=url)
template_to_load = "paginator/" + page_to_load.template_name
return render(request, template_to_load, locals())
gallery.views
from django.template.response import TemplateResponse
from gallery.models import GalleryItem
def render_gallery(request):
img_to_display = GalleryItem.objects.filter(published=True
).order_by('-date')
return TemplateResponse(request, 'gallery/gallery.html', locals())
But yes, now, I understand that something like simP will be more clean. Thanks !

flask-login can not be used in Blueprint object?

I have a question regarding flask-login and blueprint.
admin.py
admin = Blueprint('admin', __name__)
login_manager = LoginManager()
login_manager.setup_app(admin)
#login_manager.user_loader
def load_user(userid):
return User.query.get(int(userid))
#admin.route('/login', methods=["GET", "POST"])
def login():
login_form = LoginForm()
if request.method == 'POST':
#####user validation####
login_user(user)
return redirect('/')
return render_template('admin/login.html', login_form=login_form)
run.py
app = Flask(__name__)
app.config.from_object(blog_config)
app.register_blueprint(admin)
if __name__ == "__main__":
app.run(debug=True)
But when I post a form, and use login_user(user), an error occurred.
AttributeError: 'Flask' object has no attribute 'login_manager'
Then I try to use flask-login in run.py, It works fine.
run.py
login_manager = LoginManager()
login_manager.setup_app(admin)
#login_manager.user_loader
def load_user(userid):
return User.query.get(int(userid))
So, What I want to ask is,flask-login can not be used in Blueprint object?
THX!
It is also possible to LoginManager.setup_app() on Blueprint's registration:
admin = Blueprint('admin', __name__)
login_manager = LoginManager()
#admin.record_once
def on_load(state):
login_manager.init_app(state.app)
on_load will be run when the Blueprint is first registered to the app.
That's why it called setup_app
Just move initialization to your run.py and pass app as parameter
And login itself can stay inside admin blueprint