Accessing Request Data ---------------------- For web applications it's crucial to react to the data a client sends to the server. In Flask this information is provided by the global :class:`~flask.request` object. If you have some experience with Python you might be wondering how that object can be global and how Flask manages to still be threadsafe. The answer is context locals: .. _context-locals: Context Locals `````````````` .. note:: **Insider Information** If you want to understand how that works and how you can implement tests with context locals, read this section, otherwise just skip it. Certain objects in Flask are global objects, but not of the usual kind. These objects are actually proxies to objects that are local to a specific context. What a mouthful. But that is actually quite easy to understand. Imagine the context being the handling thread. A request comes in and the web server decides to spawn a new thread (or something else, the underlying object is capable of dealing with concurrency systems other than threads). When Flask starts its internal request handling it figures out that the current thread is the active context and binds the current application and the WSGI environments to that context (thread). It does that in an intelligent way so that one application can invoke another application without breaking. So what does this mean to you? Basically you can completely ignore that this is the case unless you are doing something like unit testing. You will notice that code which depends on a request object will suddenly break because there is no request object. The solution is creating a request object yourself and binding it to the context. The easiest solution for unit testing is to use the :meth:`~flask.Flask.test_request_context` context manager. In combination with the ``with`` statement it will bind a test request so that you can interact with it. Here is an example:: from flask import request with app.test_request_context('/hello', method='POST'): # now you can do something with the request until the # end of the with block, such as basic assertions: assert request.path == '/hello' assert request.method == 'POST' The other possibility is passing a whole WSGI environment to the :meth:`~flask.Flask.request_context` method:: from flask import request with app.request_context(environ): assert request.method == 'POST' The Request Object `````````````````` The request object is documented in the API section and we will not cover it here in detail (see :class:`~flask.request`). Here is a broad overview of some of the most common operations. First of all you have to import it from the ``flask`` module:: from flask import request The current request method is available by using the :attr:`~flask.request.method` attribute. To access form data (data transmitted in a ``POST`` or ``PUT`` request) you can use the :attr:`~flask.request.form` attribute. Here is a full example of the two attributes mentioned above:: @app.route('/login', methods=['POST', 'GET']) def login(): error = None if request.method == 'POST': if valid_login(request.form['username'], request.form['password']): return log_the_user_in(request.form['username']) else: error = 'Invalid username/password' # the code below is executed if the request method # was GET or the credentials were invalid return render_template('login.html', error=error) What happens if the key does not exist in the ``form`` attribute? In that case a special :exc:`KeyError` is raised. You can catch it like a standard :exc:`KeyError` but if you don't do that, a HTTP 400 Bad Request error page is shown instead. So for many situations you don't have to deal with that problem. To access parameters submitted in the URL (``?key=value``) you can use the :attr:`~flask.request.args` attribute:: searchword = request.args.get('key', '') We recommend accessing URL parameters with `get` or by catching the :exc:`KeyError` because users might change the URL and presenting them a 400 bad request page in that case is not user friendly. For a full list of methods and attributes of the request object, head over to the :class:`~flask.request` documentation. File Uploads ```````````` You can handle uploaded files with Flask easily. Just make sure not to forget to set the ``enctype="multipart/form-data"`` attribute on your HTML form, otherwise the browser will not transmit your files at all. Uploaded files are stored in memory or at a temporary location on the filesystem. You can access those files by looking at the :attr:`~flask.request.files` attribute on the request object. Each uploaded file is stored in that dictionary. It behaves just like a standard Python :class:`file` object, but it also has a :meth:`~werkzeug.datastructures.FileStorage.save` method that allows you to store that file on the filesystem of the server. Here is a simple example showing how that works:: from flask import request @app.route('/upload', methods=['GET', 'POST']) def upload_file(): if request.method == 'POST': f = request.files['the_file'] f.save('/var/www/uploads/uploaded_file.txt') ... If you want to know how the file was named on the client before it was uploaded to your application, you can access the :attr:`~werkzeug.datastructures.FileStorage.filename` attribute. However please keep in mind that this value can be forged so never ever trust that value. If you want to use the filename of the client to store the file on the server, pass it through the :func:`~werkzeug.utils.secure_filename` function that Werkzeug provides for you:: from flask import request from werkzeug.utils import secure_filename @app.route('/upload', methods=['GET', 'POST']) def upload_file(): if request.method == 'POST': f = request.files['the_file'] f.save('/var/www/uploads/' + secure_filename(f.filename)) ... For some better examples, checkout the :ref:`uploading-files` pattern. Cookies ``````` To access cookies you can use the :attr:`~flask.Request.cookies` attribute. To set cookies you can use the :attr:`~flask.Response.set_cookie` method of response objects. The :attr:`~flask.Request.cookies` attribute of request objects is a dictionary with all the cookies the client transmits. If you want to use sessions, do not use the cookies directly but instead use the :ref:`sessions` in Flask that add some security on top of cookies for you. Reading cookies:: from flask import request @app.route('/') def index(): username = request.cookies.get('username') # use cookies.get(key) instead of cookies[key] to not get a # KeyError if the cookie is missing. Storing cookies:: from flask import make_response @app.route('/') def index(): resp = make_response(render_template(...)) resp.set_cookie('username', 'the username') return resp Note that cookies are set on response objects. Since you normally just return strings from the view functions Flask will convert them into response objects for you. If you explicitly want to do that you can use the :meth:`~flask.make_response` function and then modify it. Sometimes you might want to set a cookie at a point where the response object does not exist yet. This is possible by utilizing the :ref:`deferred-callbacks` pattern. For this also see :ref:`about-responses`.