How to setup different subdomains in Flask (using blueprints)? - python

I have a Flask application running at https://app.mydomain.com.
The blueprints look like this:
app.register_blueprint(main)
app.register_blueprint(account, url_prefix='/account')
app.register_blueprint(users, url_prefix='/users')
app.register_blueprint(boxes, url_prefix='/boxes')
app.register_blueprint(api_1_0, url_prefix='/api/v1.0')
The URLs look like this:
https://app.mydomain.com
https://app.mydomain.com/account
https://app.mydomain.com/users
...
I want to move the api_1_0 route from https://app.mydomain.com/api/v1.0 to https://api.mydomain.com, how should I modify the routes and how should I set app.config['SERVER_NAME']?
example.com (without any subdomain) is another site entirely, otherwise I would get rid of the app subdomain.
So, I want app to be the default subdomain for all blueprints except api_1_0 which should be api.

Since you want your Flask application to handle multiple subdomains, you should set app.config['SERVER_NAME'] to the root domain. Then apply app as the default subdomain and overriding it in api blueprint registration.
The way to do this would be something like that I suppose:
app.config['SERVER_NAME'] = 'mydomain.com'
app.url_map.default_subdomain = "app"
app.register_blueprint(account, url_prefix='/account')
app.register_blueprint(users, url_prefix='/users')
app.register_blueprint(boxes, url_prefix='/boxes')
app.register_blueprint(api_1_0, subdomain='api')

Related

Flask routing by username at top-level route

Is there a prefered way of setting up Flask so that it routes by username (mysite.com/<username>) at the top level but still works well (and fast) for all other routes and static files?
The way I imagine it now is something like:
#app.route('/<username>', methods=['GET'])
def username_route(username):
if username_is_valid(username): # DB checks, not too fast
display_user_page(username)
render_template('user_not_found.html')
But would that have any unwanted effects on other routes or static assets, favicons, or something that I'm forgetting?
You can send data with post request on frontend for clicking profile cases.
<button onclick="urlfor('username', {'user_id': id})"/>
Top level solution is possible with app.config.
app.config['RESERVED_ROUTES'] = [
"faqs",
"settings",
"login",
...
]
Now we decide on request are user or reserved route. Because when we want to use blueprint in Flask it copy the config and give them an instance. So it is reachable for every request even you want to scale your app with blueprints.
#app.before_request
def decide_user_or_not():
if request.path in app.config['RESERVED_ROUTES']:
register_blueprint(route_blueprint)
else:
register_blueprint(user_blueprint)
Put your username_route at the end. Flask checks for each route from top to bottom. So, when you put faqs_route at the top which points to mysite.com/faqs, flask will consider that first.
Now, if you want to go to mysite.com/<username>, it will check all the top functions and since it can't find the corresponding route, it will go to the username_route at the end which will be the right route for mysite.com/<username>

How to create a private endpoint in flask

In my flask application I need to fetch data from my database whenever the users clicks a button, I know I can just make a flask route, using the flask restful module or plain routes. But my question is if I can make that route/endpoint not visible for users.
#app.route("/api/fetch/")
def fetch_data():
return some_data
I dont wan't the user having access to this endpoint directly, I just want the web application to be able to use it. Not sure if it is possible or where to look.
I found that maybe using Flask-CORS could help. Any help or guidance would be appreciated.
On flask you can use Blueprint
example from the above snippet would be
from flask import Blueprint
sample_bp = Blueprint("sample_bp", __name__)
#sample_bp.before_request
def restrict_with_token():
# Do something here on checking header or token
#sample_bp.route("/api/fetch/")
def fetch_api():
# Your logic
Otherwise you can have some referrence here : https://flask.palletsprojects.com/en/1.1.x/tutorial/views/

How to override python pyramid app config settings?

I am a newbie at Python Pyramid and working on improving an existing app that we have.
I have an app main function defined like below:
def web_main(global_config, **settings):
config = Configurator(settings=settings, root_factory=RootFactory)
...
...
config.add_request_method(get_user, "user", reify=True)
config.set_authentication_policy(authn_policy)
config.set_authorization_policy(authz_policy)
...
app = config.make_wsgi_app()
return app
I want to override get_user request method with my implementation and also want to use my own authentication policy.
With that I was thinking to do write a function like below:
def my_web_main(global_config, **settings):
app = web_main(global_config, **settings)
<Set Overrides here>
return app
Inside the config.ini file I will call my_web_main to start this app.
I have not been able to figure out how to set the overrides. Would appreciate some inputs on this.
The configurator is where you should perform overrides. So the answer is to modify web_main or define your own. Pyramid has an override mechanism via config.include(), but it does not work one level higher where you're attempting to override things with a built wsgi-app. You have to do it at the config level.

Setting global attributes in Flask framework

I am working on a small web project using Flask/Python. This is a simple client side application without database.
I want to set the REST service address as a global attribute, but haven't figured out how to do that.
I know that attributes can be seted in flask.config like this:
app = Flask(__name__)
app.config['attribute_name'] = the_service_address
but the Blueprint module cannot access the 'app' object.
Thanks a lot for your time.
Within a request context (i.e. in a view/handler) you can access the config on the current_app
from flask import current_app
current_app.config['attribute_name']
You can do this like adding an attribute to any python object:
def create_web_app():
app = Flask('foods')
setattr(app, 'cheese', CheeseService())

Pylons Routes url_for for a map.resource

How do I get the get, post, put and delete URLs for a restful routes resource using url_for?
For example, how do I get the PUT URL for a resource with id=1, and routes defined in routing.py like so:
map.resource('user', 'users', controller='user')
I know the correct URL is /users/1, but I don't want to hard code it.
Check out: http://routes.groovie.org/restful.html
url('user', id=1)
should give you '/users/1'
In routes.py your route should be:
map.resource('user', 'users/{id}', controller='user' action="some_action")
and in your controller you can get this URL with url_for like this:
url_for(controller="user", action="some_action", id=1)
Ref: Chapter 9: URLs, Routing and Dispatch, Pylons book.
I must warn you that this was used in Pylons 0.9.7, but it is not used in Pylons 1.0. url_for and redirect_to are redesigned. If you want to redirect in your controller you must write:
redirect(url(controller="user", action="some_action", id=1))
Or in your case:
url(controller="user", action="some_action", id=1)
Ref.: Pylons 1.0 Released

Categories

Resources