I know that Response is what Flask uses by default for http responses. For specific responses format, I usually use make_response. Are there any specific cases where we have to use flask.Response instead of flask.make_response? in other words, does flask.make_response work in all situations or sometimes flask.Response is the only or the better alternative? Thanks!
make_response() gives you a convenience interface, one that will take arguments in more formats than the flask.Response() object takes.
In addition, make_response() uses the Flask.response_class attribute (so app.response_class) to build the response. The default value for Flask.response_class is flask.Response, but you can set this value to a subclass instead.
So you should really always use make_response(), rather than use flask.Response() directly, especially if you want to support swapping out what Response class you actually use for responses.
You may have to use app.response_class directly if it is a subclass that takes arguments that make_response() can't supply.
Related
I'm working with a small Python server written with Flask, and I'm seeing some very weird behavior with HTTP request objects.
When I receive a request, I immediately attempt to log request.__dict__. However, upon retrieving my logs, I noticed that request.__dict__ does not contain the actual body of the request (it should be in request.data).
I then decided to log request.data, and instead of None like I was expecting, since I didn't see it in request.__dict__, I saw the contents of the request body.
Even more interestingly, as soon as I placed the request.data line above the request.__dict__ line, the output from logging request.__dict__ also contained the data property.
It's almost like request.data does not exist until I attempt to access it for the first time. Is this some weird behavior with Flask's request object? Are there any other properties that behave like this? What's the best practice for making sure the request object is fully "loaded"?
Flask's (actually Werkzeug's) Request class doesn't have a data attribute to start with: it has a data method wrapped with the #cached_property decorator. As you can see from the implementation of that decorator, when the property is first accessed, it creates an entry in __dict__ to contain the value returned by the function, which has the effect of avoiding the need to recalculate it each time - basically, a form of memoization.
Although the implementation is very clever (as you'd expect from Armin), there's nothing particularly surprising about the effect - there are plenty of ways that an attribute would not be found in __dict__.
I use Google APIs Client Library for Python to work with Fusion Tables API. importRows method here requires to provide the data in the body. How should I do it?
response = service.table().importRows(tableId=TABLE_ID, body='zzz,yyy').execute()
returns the error - Got an unexpected keyword argument "body".
There's a slight subtlety here -- the body of the request should be the Table resource, if you want to update it; the contents (in this case, the rows) should actually be passed as a media upload.
In the python client, this means you want to pass something in to the media_body argument, not body. You can't just pass a literal string -- you need to wrap the data in either a MediaFileUpload or MediaInMemoryUpload. (For the case here, you want the latter, but if you've got a file with rows on disk, you want the former.)
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.
I have written a plugin that sends a signal to activate my code. However, it doesn't send the user-request object to my code. I am looking for a way to retrieve the current request without modifying the main application. I cannot find any documentation related to global request (like $_SERVER['REMOTE_ADDR'] in PHP).
I would like to know if there are any variable to do like that in Python/Django.
Django doesn't provide a global request object (it would actually be a thread local, not a global). But there are a few techniques you can use to get the same effect yourself: http://nedbatchelder.com/blog/201008/global_django_requests.html
AFAIK it is not available, except you make it available.
You can copy+paste the snippets provided in the other answers, or you can use this library: https://pypi.python.org/pypi/django-crequest
Middleware to make current request always available.
you can attach it to current request via middleware and retrieve it back
https://github.com/jedie/django-tools/blob/master/django_tools/middlewares/ThreadLocal.py
Based on Ned Batchelder's reply I've compiled a solution. Although I wouldn't recommend it for anything but debugging/troubleshooting. There's a better solution on the linked page.
Put module m1 at a project root:
import inspect
def get_request():
for f in inspect.stack():
f_code = inspect.getmembers(f.frame, inspect.iscode)[0][1]
f_locals = [v for (n, v) in inspect.getmembers(f.frame) if n == 'f_locals'][0]
co_varnames = [v for (n, v) in inspect.getmembers(f_code) if n == 'co_varnames'][0]
if 'request' in co_varnames:
return f_locals['request']
Then in any other file:
import m1
print(m1.get_response().path)
You might want to make sure you don't introduce reference cycles. I haven't understood under which particular conditions I must do what exactly. Not that it matters in my case. But your mileage might vary.
One solution is django-middleware-global-request.
It provides a way to get the request from anywhere once the request has been constructed by Django in the first place. It returns None if no request object is available, for example when running in a manage.py shell.
As I know it, you define your Django view using a number of methods like:
def detail(request, some_param):
# [...]
The parameter request contains information about the HTTP request. request.META['HTTP_X_FORWARDED_FOR'] for example, returns the client's IP address.
If your plugin has something to do with requests, its classes and function probably will be instantiated/called from your view. This means you need to pass it the current request object, as it makes no sense to have a global request object around.
In PHP, this is possible, as every request causes the whole code to be executed from scratch, but in Django requests are dispatched by a server and passed around in the framework using HttpRequest objects. Also refer to this part of the Django documentation for more information.
I'm wondering if there's a clever pattern for request-scoping arbitrary information without resorting to either TLS or putting the information in the session.
Really, this would be for contextual attributes that I'd like to not look up more than once in a request path, but which are tied to a request invocation and there's no good reason to let them thresh around in the session.
Something like a dict that's pinned to the request where I can shove things or lazy load them. I could write a wrapper for request and swap it out in a middleware, but I figured I'd check to see what best-practice might be here?
Just assign the dictionary directly to the request. You can do that in middleware or in your view, as you like.
Context processors. They are called once for every request and receive the actual request object - so you can add ANY data to the context, also based on the curent request!