Flask filter by url - python

I'm using Flask-Restless and Flask-SQLAlchemy on my application. I can't remember when, but I did a example that I'm almost 100% it was with Flask-Restless to filter a query in the url like /example?id=1. Although the pagination plugin is ok, I can't replicate the filtering by attribute on the url.
I've been searching like crazy on how to do that again but I can't find it. I'd appreciate if someone here has a way of doing that.
PS.: With Flask-Restless, how do I make a GET request on a endpoint passing a parameter like GET /example {"id": 1}?
PS2.: I know that if I put the id after the "/" I'll get the object, but I want to filter any field I want.

Related

Flask and SQLAlchemy sort in display without new query?

I'm displaying the results from an SQLAlchemy (Flask-SQLAlchemy) query on a particular view. However the sorting/order is only set by what I originally passed into the query ( order_by(desc(SelectedTable.date_changed)) ). I'm trying to now add functionality that each column that is displayed can be selected to order the presentation.
Is there a way to alter the way a returned query object is sorted once it's returned to create this behavior? Or will I need to build custom queries for each possible column that could be sorted by and ascending/descending?
Is there a recipe for implementing something like this? I've tried google, here, the Flask, Flask-SQLAlchemy, and SQLAlchemy docs for something along these lines but haven't seen anything that touches on the subject and beginning to think that I'm going to need to use custom queries or without new queries try some JavaScript in the Jinja Template to achieve this.
Thanks!

Flask GET - Retrieve an undetermined number of parameters in the URL

WHAT: I have a Flask server and I would like to build a route and pass it an undetermined number of parameters via a GET method.
WHY: I would like to give the user the ability to pick several dates from a date picker, and give this list to the server which would make an SQL request to my database to retrieve data corresponding to those dates selected by the user. There would be hundreds of files and I would also limit the number of requests/responses made for performance as much as possible.
I have little experience with Flask but enough to handle routes like:
#app.route('/photos/year=<int:year>&month=<string:month>', methods=['GET'])
or even :
#app.route('/photos/<year>.<month>', methods=['GET'])
I have 3 cases :
The user has the ability to choose an interval of dates, in which case I would use a route like '/photos/< dateFrom> _ to _< dateTo>' (without spaces) ;
or a single date, in which case I would use a route like '/photos/< date >'
or multiple dates non-necessarily contiguous, and I don't know how to handle it, but what I would do would look like something like this : '/photos/< date1>.< date2>?.< date3>?...'
('?': representing an optional parameter ; '...': representing an undetermined number of parameters, just like in programming language (actually this would be enough : '/photos/< date>...' if a syntax like '...' exists).
I've been looking for answers but couldn't find something. The only thing that may be interesting is passing a JSON object, but yet I don't know how to deal with this, I'm going to look to it until I get an answer. I will also have a look to Flask-RESTful extension in case it helps.
Any help would be appreciated.
I don't think there is a need for separate routes for three use cases. You might want to have a single GET route and receive dates as url params.
In this case your flask route will become:
#app.route('/photos', methods=['GET'])
you can now pass any key value pair in url as
/photos?date1=1&date2=2
you can access these params using
from flask import request
date1 = request.args.get('date1')
date2 = request.args.get('date2')
If you want a list of date just send them using same key in the URL and use
request.args.getlist(<paramname>)
However since in your case the keys that will come as parameters may vary from request to request, be careful to check if the key you are trying to use exist in the request that came. I recommend you to go through documentation of request object for more details.
However as a general practice if your parameters are more complex you can consider using JSON objects as payload instead of URL params.

URL path parameters vs query parameters in Django

I've looked around for a little while now and can't seem to find anything that even touches on the differences. As the title states, I'm trying to find out what difference getting your data via url path parameters like /content/7 then using regex in your urls.py, and getting them from query params like /content?num=7 using request.GET.get() actually makes.
What are the pros and cons of each, and are there any scenarios where one would clearly be a better choice than the other?
Also, from what I can tell, the (Django's) preferred method seems to be using url path params with regex. Is there any reason for this, other than potentially cleaner URLs? Any additional information pertinent to the topic is welcome.
This would depend on what architectural pattern you would like to adhere to. For example, according to the REST architectural pattern (which we can argue is the most common), you want do design URLs such that without query params, they point to "resources" which roughly correspond to nouns in your application and then HTTP verbs correspond to actions you can perform on that resource.
If, for instance, your application has users, you would want to design URLs like this:
GET /users/ # gets all users
POST /users/ # creates a new user
GET /users/<id>/ # gets a user with that id. Notice this url still points to a user resource
PUT /users/<id> # updates an existing user's information
DELETE /users/<id> # deletes a user
You could then use query params to filter a set of users at a resource. For example, to get users that are active, your URL would look something like
/users?active=true
So to summarize, query params vs. path params depends on your architectural preference.
A more detailed explanation of REST: http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api
Roy Fielding's version if you want to get really academic: http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm

URL Separation in Flask

I am listening to a Flask URL of the form,
http://example.com:8080/v1/api?param1=value1&param2=value2&param3=value3&param4=value4
Now, I want to achieve URL separation of the parameters in either of the below forms, (ForwardSlash)
http://example.com:8080/v1/api?param1=value1&param2=value2/parameters?param3=value3&param4=value4
OR (Semicolon)
http://example.com:8080/v1/api?param1=value1&param2=value2;parameters?param3=value3&param4=value4
I know these are not clean URLs and need to be avoided, but such is the usecase.
I am currently listening to the URL as,
#app.route('/v1/api', methods=['GET','POST'])
def api_call():
#....code for listening ...
How do I modify my code to get the URL separation as desired above?
I understand I am not following good principles of URL formation or other design principles, this is a use case requirement and am stuck on achieving this through Flask.
Instead of passing all the values as query params, can you use form-post to achieve this? You can pass an object using this method and will give you more flexibility on the type of data-structure that you want to achieve.

Dynamically add URL rules to Flask app

I am writing an app in which users will be able to store information that they can specify a REST interface for. IE, store a list of products at /<username>/rest/products. Since the URLs are obviously not known before hand, I was trying to think of the best way to implement dynamic URL creation in Flask. The first way I thought of would be to write a catch-all rule, and route the URL from there. But then I am basically duplicating URL routing capabilities when Flask already has them built-in. So, I was wondering if it would be a bad idea to use .add_url_rule() (docs here, scroll down a bit) to attach them directly to the app. Is there a specific reason this shouldn't be done?
Every time you execute add_url_rule() the internal routing remaps the URL map. This is neither threadsafe nor fast. I right now don't understand why you need user specific URL rules to be honest. It kinda sounds like you actually want user specific applications mounted?
Maybe this is helpful: http://flask.pocoo.org/docs/patterns/appdispatch/
I have had similar requirement for my application where each endpoint /<SOMEID>/rest/other for given SOMEID should be bounded to a different function. One way to achieve this is keeping a lookup dictionary where values are the function that handle the specific SOMEID. For example take a look at this snippet:
func_look_up_dict = {...}
#app.route('<SOMEID>/rest/other', methods=['GET'])
def multiple_func_router_endpoint(SOMEID):
if SOMEID in func_look_up_dict.keys():
return jsonify({'result' = func_look_up_dict[SOMEID]()}), 200
else:
return jsonify({'result'='unknown', 'reason'='invalid id in url'}), 404
so for this care you don't really need to "dynamically" add url rules, but rather use a url rule with parameter and handle the various cases withing a single function. Another thing to consider is to really think about the use case of such URL endpoint. If <username> is a parameter that needs to be passed in, why not to use a url rule such as /rest/product/<username> or pass it in as an argument in the GET request?
Hope that helps.

Categories