Define a base route when using flask blueprints - python

I am currently using blueprints in my flask application. However, I would like to define a simple 'base' route ( '/' ) e.g. myapp.com/
How can I do this?

IMHO, this has nothing to do with Flask. To create route to home page, You would do something like this:
#app.route
def index():
return render_template('index.html')
Visiting / on any site where this Flask app is deployed would lead to home page.
Now, in order to lead You to myapp.com/, You need to get myapp.com address, meaning You would need to buy that domain.

Related

How do I implement a ReactJS app into my Flask app?

I have a ReactJS frontend with multiple routes. e.g.: /, /example1, example1/example2/example3/example4.
I have used the react-build script to make production build of the ReactJS app. Now I'm trying to incorporate the ReactJS app with the Flask app.
This is what I have so far on my Flask routes:
app = Flask(__name__, static_folder="./build", static_url_path="")
CORS(app)
app.secret_key = secret_key
#app.route("/", defaults={"path": ""})
#app.route("/<path:path>")
def serve(path):
return app.send_static_file("index.html")
This works, but not for all routes. For example, /example1 and /example1/example2 work. But /example1/example2/example3 doesn't work. Any ideas? Thanks.
EDIT:
It turns out that /example1/example2 does not work, meaning that the issue is to do with custom routes, which aren't predefined. All routes which I have specifically defined work, but the dynamically made ones don't.
https://blog.miguelgrinberg.com/post/how-to-deploy-a-react-router-flask-application - this might help you for now, the tutorial has modified the 404 exception handler (Not really an elegant solution but works).
#app.errorhandler(404)
def not_found(e):
return app.send_static_file('index.html')

flask Function to create route

i'm building an app similar to myPhpAdmain
i need to allow users in session to create route (aka: #app.route) for the page they require
#app.route('/<x>')
def <x>():
return render_template (<x>+'.html')
where x is a variable that has been given by a user through the front-end
x = request.form.get('x')
how can I allow users to create Pages route like that by a function without allowing them to write it themselves in my flask app ?
Use variable routing:
#app.route('/<x>')
def user_route(x):
return render_template(f"{x}.html")

Flask-Login: How to set "blueprint_login_views" to have blueprint specific login_view

Any help on how to use login_view for each blueprint? I did a search on Google, your blogs, and every possible sources but didn't find any working examples.
I have 4 blueprints as below:
admin(__init__, route.py)
customer(__init__, route.py)
partners(__init__, route.py)
auth(__init__, route.py)
auth is going to handle as a central point for different type(social+regular) of authentication.
And I am using #login_required for all the possible routes under different profiles.
But the problem is; login_manager.login_view only allows me to setup only one login view. I want to have separate login_views so that my respective authorization can be redirected to respective blueprints and so on and I can have a clear control on who(role) is logging in and it's respective route.
I only found something
#LoginManager.login_view blueprint_login_views
that when unauthorized() is called it can first check blueprint_login_views and if not set then login_views is checked and then "HTTP 401 (Unauthorized) error" is raised if nothing is set. But there is no working example how to set blueprint_login_views through login_manager. Please help.
OP's original answer properly formatted:
I myself could solve this now. I removed "login_manager.login_view"
and added the below block in app/init.py after the blueprints are
loaded.
login_manager.blueprint_login_views = {
'partners': '/partner/login',
'customers': '/customer/login',
'admin' : '/admin/login',
}
The answer above works great. If you have two tables that you need to query from for each blueprint authentication, you can do:
#login_manager.user_loader
def load_user(user_id):
x = Users.query.get(str(user_id))
if x == None:
x = Admins.query.get(str(user_id))
return x
This resides where you declare the flask app instance typically init.py file(not empty)

Flask-Restful ignores blueprint's url_prefix

I want to use Flask blueprints to organize my Flask-Restful resources into separate url prefixes. Regardless of what url prefix I set (during either blueprint creation or registration), everything gets mapped to the raw route paths. How do I correctly use Restful with blueprints?
app = Flask(__name__)
api = Api(app)
api.add_resource(Building, '/<int:id>', endpoint='building')
api.add_resource(Jack, '/<int:id>', endpoint='jack')
building_api = Blueprint('building_api', __name__)
jack_api = Blueprint('jack_api', __name__)
app.register_blueprint(building_api, url_prefix='/buildings')
app.register_blueprint(jack_api, url_prefix='/jacks')
All documentation I can find says that these should now be available at /buildings/<int:id> and /jacks/<int:id>, but both of those urls 404 and instead I can access the building one at /<int:id>. Hard coding the path in add_resource fixes it, but defeats the point of url_prefix.
You need to pass the blueprint to the Api instance, not the app.
building_bp = Blueprint('buildings', __name__)
building_api = Api(building_bp)
building_api.add_resource(Building, '/<int:id>')
app.register_blueprint(building_bp, url_prefix='/buildings')
This is zhe best way to do with blueprint:
from flask import Flask, Blueprint
from flask_restful import Api, Resource, url_for
app = Flask(__name__)
api_bp = Blueprint('api', __name__)
api = Api(api_bp)
class TodoItem(Resource):
def get(self, id):
return {'task': 'Say "Hello, World!"'}
api.add_resource(TodoItem, '/todos/<int:id>')
app.register_blueprint(api_bp)
you should send Blueprint'instance to Api
I do not know why but I struggled using the Blueprint as mentioned in the answers.
But here's a quick solution I found while going through the doc link. Making use of the prefix parameter in Api() does the job.
app = Flask(__name__)
api = Api(app, prefix='/buildings')
Now, all your routes will be prefixed with /buildings. Just make sure you use url_for('link') in places where you might have simply used a /link.
One more strange thing I noticed is that atleast for me, it did not work until I renamed my routes to the same name as their class names. For example, Class Home(Resource) should have a route to /home. Using /homeepage or any other route for Home Class causes an error. Not sure if it is only me.

How to create dynamic subdomains in a Flask application

I am trying to setup variable route handling in a Flask application such as described in this answer: Dynamic Subdomain Handling in a Web App (Flask)
However, I want to be able to recognize certain subdomains BEFORE they are caught by the variable route so I can use the flask-restful api extension (Routing with RESTful).
For example, I have tried the following:
#app.route('/', subdomain="<user>", defaults={'path':''})
#app.route('/<path:path>', subdomain="<user>")
def user_profile(user,path):
pass
class Api(restful.Resource):
def get(self):
#Do Api things.
api.add_resource(Api, '/v1', subdomain="api")
When I test this, all of URLs go to the variable route handler and call user_prof(). I tried putting the api route first and the standard #app.route rule second and vice versa but there was no change.
Am I missing some other parameter or need to go deeper in Flask to make this happen?
Update:
The URL patterns I am trying to match are like this:
user1.mysite.com -> handled by user_profile()
user2.mysite.com -> handled by user_profile()
any_future_string.mysite.com -> handled by user_profile()
api.mysite.com/v1 -> handled by Api class
Other cases include:
www.mysite.com -> handled by index_display()
mysite.com -> handled by index_display()
#app.before_request
def before_request():
if 'api' == request.host[:-len(app.config['SERVER_NAME'])].rstrip('.'):
redirect(url_for('api'))
#app.route('/', defaults={'path': ''}, subdomain='api')
#app.route('/<path:path>', subdomain='api')
def api(path):
return "hello"
This should work. Add your api version to the path if needed or that could be processed by your API class.
To keep it simple, I redesigned the logic of my application into two distinct parts.
This way the Flask application only handles the API endpoint logic. The user profile logic is handled by another application. I can now add multiple Resources to the API application without worry about breaking the routing.

Categories