Python: pipe request to blueprint endpoint through another endpoint - python

I have a Flask application that inherits a library with some blueprints already defined (that I can't change). Now I need to be able to filter out some of the requests that goes to one of the pre-defined endpoints.
The endpoint /updateuser is defined in the blueprint, but now I need to stop certain requests from getting to that endpoint, and instead return a message in my application.
I've figured out how to overwrite an endpoint in a blueprint, but that's not what I want. I'd like to add this /updateuser endpoint in my flask application, and either return a message OR send them to the original endpoint that's defined in the library, without the user being exposed to this extra layer.
Is there any good way to achieve this?

Related

Flask Backend with React Frontend, Using OAuth

This question's being asked a ton before, but I really don't think there's a clear answer anywhere (that I've read, anyway).
The Set Up
I have a Flask backend, solely serving an API. I've configured OAuth (with Google), using LoginManager. The login flow works perfectly, and I end up with session cookie, which permits me to access endpoints decorated with the #login_required decorator.
The frontend is to be written separately in React.
The Complication
The cookie set by going through the OAuth flow does not get used by the frontend doing the calling. All calls from the frontend to the backend end up with a 401, because unsurprisingly, the URL for the cookie is not the same as the URL for the backend which set it.
Idea
I have an unprotected /login endpoint, which I allow the frontend to call. Similarly the /login/callback endpoint can be called to finish the flow, and get back tokens. Could these somehow be used safely with the frontend, but with the flow still happening in the backend?
Compromise
What we've ended up with now, is the frontend doing the OAuth flow completely, then sending the token it gets along with every single call. The backend then does a check with Google every time to see if the token is indeed valid for who the frontend says it is.
This is less than ideal.
What is the recommended and correct way of separating the frontend and backend, but keeping the auth in the backend?

Flask redirect alternative in Seldon core

I have a kibana dashboard where there are some links provided for the user to click on. The link calls a flask service, which does some processing and redirects an URL using flask's redirect API, so that Kibana dashboard shows the processed values. Now, the flask is replaced with seldon core for predictions. Is there any way to redirect an URL, like it can be done in flask?
Thanks in advance.
Have you completely removed the flask app? If not you can use the flask to handle all interactions with the frond end and just use Seldon for the predictions.
This is a micro-services approach. You can receive the request as you used to in flask and then from within flask call the Seldon micro-service, get the prediction and then redirect to the results page with the new results from within flask.
This is good because if you change your prediction logic or tools in the future you wont have to redo all this work. You ll just change the function that flask calls to get the results. Also you frond end and back-end will be agnostic of the implementation details of the prediction method.

Why can't I use flask.g after a request comes?

According to the Flask 0.12 docs:
flask.g
...... Starting with Flask 0.10 this is stored on the application
context and no longer on the request context which means it becomes
available if only the application context is bound and not yet a
request.
As far as I know, when a request comes, a application context will be created, if there isn't one. So shouldn't flask.g be available after a request has come, since the request ensures the existence of an application context?
As a bouns question: why should I store database connections on g instead of request? I know creating a application context is less "expensive" than creating a request context, but when a request comes, a request context will be created anyway.
The wording there is a little awkward. The g object is available during a request as well. A request context is nested inside an application context.
You should store a database connection in the g object because it'll be available *even when there is no request, such as in the flask shell command, and any custom command-line commands. You'll need this when initialising your database, for example.
Next, there are advanced use-cases where you may want to create an 'internal' request, calling another route on your Flask app as if it came from outside. This nested request would re-use the existing app context.
There is never a request context without an application context.
Answering bonus question from Flask documentation:
For instance, the request variable is the request object associated
with the current request, whereas g is a general purpose variable
associated with the current application context.
flask.g is bound to the session of current request. That means that you have different g's for different requests. For example, I store a user in g object for easier access to it (it's not good, but fast to access and easy to use)

How is Flask-Login's request_loader related to user_loader?

I apologize in advance for asking a rather cryptic question. However, I did not understand it despite going through a lot of material. It would be great if you could shed some light on this.
What is the purpose of a request_loader in flask-login? How does it interact with the user_loader decorator?
If I am using a token based authentication system (I am planning on sending the token to my angularJS front end, storing the token there and sending that token in the authorization-token header), will I need a request_loader or will a user_loader (where I check the auth header and see if the user exists) suffice?
From the Flask-Login documentation:
Sometimes you want to login users without using cookies, such as using
header values or an api key passed as a query argument. In these cases,
you should use the request_loader callback. This callback should
behave the same as your user_loader callback, except that it accepts
the Flask request instead of a user_id.
So, to answer your question, they both serve the same function for Flask-Login. They are both used to load the user. request_loader, however, is appropriate for custom logins.
Here's a great tutorial I found that utilizes request_loader to take advantage of token based authentication (The post is not my own, I'm merely sharing the link): http://gouthamanbalaraman.com/blog/minimal-flask-login-example.html
I need to make this clear.
This is the reason why you shoud use request_loader with flask_login.
There will be a lot of #login_required from flask_login used in your api to guard the request access.
You need to make a request to pass the check of auth.
And there will be a lot of current_user imported from flask_login,
Your app need to use them to let the request act as the identity of the current_user.
There are two ways to achieve the above with flask_login.
Using user_loader makes the request to be OK for #login_required.
It is often used for UI logins from browser.
It will store session cookies to the browser and use them to auth later.
So you need to login only once and the session will keep for a time.
Using request_loader will also be OK with #login_required.
But it is often used with api_key or basic auth.
For example used by other apps to interact with your flask app.
There will be no session cookies,
so you need to provide the auth info every time you send request.
With both user_loader and request_loader,
now you got 2 ways of auth for the same api,
protected by #login_required,
and with current_user usable,
which is really smart.
To verify users with Flask-Login's session_id for frontend requests through Angular, you must set the withCredentials configuration flag to true.
That is, if you are using Angular's $http.post(url,data [,config]) or $http.get(url [,config]), make sure the config object contains the property withCredentials set to true. This will instruct the browser to use its cookies in the same way it would for a full-on page visit.
For example,
$http.post('/api/login',{username:'myusername',password:'mypassword'},{withCredentials:true})
will post the data {username:'myusername',password:'mypassword'} to your site/app's /api/login route and, if you're using Flask-Login and are logged in, Flask will know.
You can set this behavior for all $http service requests by setting
$httpProvider.defaults.withCredentials=true
somewhere in your app. Currently, I have that line of code in my app.config block, which seems appropriate to me:
var myApp = angular.module('myApp');
myApp.config(function ($httpProvider) {
$httpProvider.defaults.withCredentials = true;
});
(Since this post is about Flask, folks may want to send form data through Angular in such a way that it can be found in request.form, which has a similar solution, fyi.)

Flask for Python - architectural question regarding the system

I've been using Django and Django passes in a request object to a view when it's run. It looks like (from first glance) in Flask the application owns the request and it's imported (as if it was a static resource). I don't understand this and I'm just trying to wrap my brain around WSGI and Flask, etc. Any help is appreciated.
In Flask request is a thread-safe global, so you actually do import it:
from flask import request
I'm not sure this feature is related to WSGI as other WSGI micro-frameworks do pass request as a view function argument. "Global" request object is a feature of Flask. Flask also encourages to store user's data which is valid for a single request in a similar object called flask.g:
To share data that is valid for one
request only from one function to
another, a global variable is not good
enough because it would break in
threaded environments. Flask provides
you with a special object that ensures
it is only valid for the active
request and that will return different
values for each request. In a
nutshell: it does the right thing,
like it does for request and session.

Categories

Resources