Pylons Routes url_for for a map.resource - python

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

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/

url_for in celery doesn't work

We are building a notofication mailing system as part of a python/flask system, as for now it has been run using cronjobs but we're moving everything to celery to make it more performant and easier to maintain.
However the templates which have been working so far suddendly start throwing the following error:
[2017-05-29 20:30:30,411: WARNING/PoolWorker-7] [2017-05-29 20:30:30,411]
ERROR in mails: ERROR errorString => Could not build url for endpoint
'page.start' with values ['from_email']. Did you mean 'static' instead?
The url_for is called in an external template as follows:
{{ url_for('page.start', _external=True) }}
and rendered as follows:
message = render_template('notifs/user_notif.html',
subject=subject,
entries = grouped,
user=u,
unsubscribe_hash=pw_hash,
list_id = str(notif_list.id),
timestamp = today)
Now if we rip out all the url_for in the template it works. But why?
My hypothesis, which i can't test or proof: Somehow celery does not have access to the Blueprints (even though it is running in the application context, as the tasks actually accesses all kinds of models and the db etc.). How do I make celery understand url_for?
Just ran into the same issue:
The database and models are fronted by by your ORM (Flask-sqlalchemy?), not the Flask application itself. Flask the application provides the context for things like url_for, current_user, etc. Your orm just provides the database abstraction and is not contingent on the actual application context.

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

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')

Flask and url rewrite

Is it possible to do url rewrite with Flask under Nginx+uWSGI?
I need to add SEO links, so pages of Flask website should be available with two links, for example:
/post/3 and /2014_10_08_post_title.
Connections between normal link and SEO link should be stored in database.
What is the easist way to do it? Is it better and faster way to do it within Flask app or it can be done within nginx?
Thanks!
Flask allows routing multiple URLs to the same view:
#route('/post/<post_id>', defaults={'seo_url': None})
#route('/<seo_url>', defaults={'post_id': None})
def view(post_id, seo_url):
if post_id:
...
elif seo_url:
...

Categories

Resources