diff options
Diffstat (limited to 'app/static/doc/flask-docs/_sources/quickstart.txt')
-rw-r--r-- | app/static/doc/flask-docs/_sources/quickstart.txt | 824 |
1 files changed, 0 insertions, 824 deletions
diff --git a/app/static/doc/flask-docs/_sources/quickstart.txt b/app/static/doc/flask-docs/_sources/quickstart.txt deleted file mode 100644 index 34aa3be..0000000 --- a/app/static/doc/flask-docs/_sources/quickstart.txt +++ /dev/null @@ -1,824 +0,0 @@ -.. _quickstart: - -Quickstart -========== - -Eager to get started? This page gives a good introduction in how to get -started with Flask. This assumes you already have Flask installed. If -you do not, head over to the :ref:`installation` section. - - -A Minimal Application ---------------------- - -A minimal Flask application looks something like this:: - - from flask import Flask - app = Flask(__name__) - - @app.route('/') - def hello_world(): - return 'Hello World!' - - if __name__ == '__main__': - app.run() - -Just save it as `hello.py` or something similar and run it with your -Python interpreter. Make sure to not call your application `flask.py` -because this would conflict with Flask itself. - -:: - - $ python hello.py - * Running on http://127.0.0.1:5000/ - -Head over to `http://127.0.0.1:5000/ <http://127.0.0.1:5000/>`_, you should -see your hello world greeting. - -So what did that code do? - -1. First we imported the :class:`~flask.Flask` class. An instance of this - class will be our WSGI application. The first argument is the name of - the application's module. If you are using a single module (like here) - you should use `__name__` because depending on if it's started as - application or imported as module the name will be different - (``'__main__'`` versus the actual import name). For more information - on that, have a look at the :class:`~flask.Flask` documentation. -2. Next we create an instance of it. We pass it the name of the module / - package. This is needed so that Flask knows where it should look for - templates, static files and so on. -3. Then we use the :meth:`~flask.Flask.route` decorator to tell Flask - what URL should trigger our function. -4. The function then has a name which is also used to generate URLs to - that particular function, and returns the message we want to display in - the user's browser. -5. Finally we use the :meth:`~flask.Flask.run` function to run the - local server with our application. The ``if __name__ == '__main__':`` - makes sure the server only runs if the script is executed directly from - the Python interpreter and not used as imported module. - -To stop the server, hit control-C. - -.. _public-server: - -.. admonition:: Externally Visible Server - - If you run the server you will notice that the server is only available - from your own computer, not from any other in the network. This is the - default because in debugging mode a user of the application can execute - arbitrary Python code on your computer. If you have `debug` disabled - or trust the users on your network, you can make the server publicly - available. - - Just change the call of the :meth:`~flask.Flask.run` method to look - like this:: - - app.run(host='0.0.0.0') - - This tells your operating system to listen on a public IP. - - -Debug Mode ----------- - -The :meth:`~flask.Flask.run` method is nice to start a local -development server, but you would have to restart it manually after each -change you do to code. That is not very nice and Flask can do better. If -you enable the debug support the server will reload itself on code changes -and also provide you with a helpful debugger if things go wrong. - -There are two ways to enable debugging. Either set that flag on the -application object:: - - app.debug = True - app.run() - -Or pass it to run:: - - app.run(debug=True) - -Both will have exactly the same effect. - -.. admonition:: Attention - - Even though the interactive debugger does not work in forking environments - (which makes it nearly impossible to use on production servers), it still - allows the execution of arbitrary code. That makes it a major security - risk and therefore it **must never be used on production machines**. - -Screenshot of the debugger in action: - -.. image:: _static/debugger.png - :align: center - :class: screenshot - :alt: screenshot of debugger in action - -.. admonition:: Working With Other Debuggers - - Debuggers interfere with each other. If you are using another debugger - (e.g. PyDev or IntelliJ), you may need to set ``app.debug = False``. - - -Routing -------- - -Modern web applications have beautiful URLs. This helps people remember -the URLs which is especially handy for applications that are used from -mobile devices with slower network connections. If the user can directly -go to the desired page without having to hit the index page it is more -likely they will like the page and come back next time. - -As you have seen above, the :meth:`~flask.Flask.route` decorator is used -to bind a function to a URL. Here are some basic examples:: - - @app.route('/') - def index(): - return 'Index Page' - - @app.route('/hello') - def hello(): - return 'Hello World' - -But there is more to it! You can make certain parts of the URL dynamic -and attach multiple rules to a function. - -Variable Rules -`````````````` - -To add variable parts to a URL you can mark these special sections as -``<variable_name>``. Such a part is then passed as keyword argument to -your function. Optionally a converter can be specified by specifying a -rule with ``<converter:variable_name>``. Here are some nice examples:: - - @app.route('/user/<username>') - def show_user_profile(username): - # show the user profile for that user - pass - - @app.route('/post/<int:post_id>') - def show_post(post_id): - # show the post with the given id, the id is an integer - pass - -The following converters exist: - -=========== =========================================== -`int` accepts integers -`float` like `int` but for floating point values -`path` like the default but also accepts slashes -=========== =========================================== - -.. admonition:: Unique URLs / Redirection Behaviour - - Flask's URL rules are based on Werkzeug's routing module. The idea - behind that module is to ensure nice looking and also unique URLs based - on behaviour Apache and earlier servers coined. - - Take these two rules:: - - @app.route('/projects/') - def projects(): - pass - - @app.route('/about') - def about(): - pass - - They look rather similar, the difference is the trailing slash in the - URL *definition*. In the first case, the canonical URL for the - `projects` endpoint has a trailing slash. It's similar to a folder in - that sense. Accessing it without a trailing slash will cause Flask to - redirect to the canonical URL with the trailing slash. - - However in the second case the URL is defined without a slash so it - behaves similar to a file and accessing the URL with a trailing slash - will be a 404 error. - - Why is this? This allows relative URLs to continue working if users - access the page when they forget a trailing slash. This behaviour is - also consistent with how Apache and other servers work. Also, the URLs - will stay unique which helps search engines not indexing the same page - twice. - - -.. _url-building: - -URL Building -```````````` - -If it can match URLs, can it also generate them? Of course it can. To -build a URL to a specific function you can use the :func:`~flask.url_for` -function. It accepts the name of the function as first argument and a -number of keyword arguments, each corresponding to the variable part of -the URL rule. Unknown variable parts are appended to the URL as query -parameter. Here are some examples: - ->>> from flask import Flask, url_for ->>> app = Flask(__name__) ->>> @app.route('/') -... def index(): pass -... ->>> @app.route('/login') -... def login(): pass -... ->>> @app.route('/user/<username>') -... def profile(username): pass -... ->>> with app.test_request_context(): -... print url_for('index') -... print url_for('login') -... print url_for('login', next='/') -... print url_for('profile', username='John Doe') -... -/ -/login -/login?next=/ -/user/John%20Doe - -(This also uses the :meth:`~flask.Flask.test_request_context` method -explained below. It basically tells Flask to think we are handling a -request even though we are not, we are in an interactive Python shell. -Have a look at the explanation below. :ref:`context-locals`). - -Why would you want to build URLs instead of hardcoding them in your -templates? There are three good reasons for this: - -1. reversing is often more descriptive than hardcoding the URLs. Also and - more importantly you can change URLs in one go without having to change - the URLs all over the place. -2. URL building will handle escaping of special characters and Unicode - data transparently for you, you don't have to deal with that. -3. If your application is placed outside the URL root (so say in - ``/myapplication`` instead of ``/``), :func:`~flask.url_for` will - handle that properly for you. - - -HTTP Methods -```````````` - -HTTP (the protocol web applications are speaking) knows different methods -to access URLs. By default a route only answers to `GET` requests, but -that can be changed by providing the `methods` argument to the -:meth:`~flask.Flask.route` decorator. Here are some examples:: - - @app.route('/login', methods=['GET', 'POST']) - def login(): - if request.method == 'POST': - do_the_login() - else: - show_the_login_form() - -If `GET` is present, `HEAD` will be added automatically for you. You -don't have to deal with that. It will also make sure that `HEAD` requests -are handled like the `HTTP RFC`_ (the document describing the HTTP -protocol) demands, so you can completely ignore that part of the HTTP -specification. Likewise as of Flask 0.6, `OPTIONS` is implemented for you -as well automatically. - -You have no idea what an HTTP method is? Worry not, here is a quick -introduction to HTTP methods and why they matter: - -The HTTP method (also often called "the verb") tells the server what the -clients wants to *do* with the requested page. The following methods are -very common: - -`GET` - The browser tells the server to just *get* the information stored on - that page and send it. This is probably the most common method. - -`HEAD` - The browser tells the server to get the information, but it is only - interested in the *headers*, not the content of the page. An - application is supposed to handle that as if a `GET` request was - received but to not deliver the actual content. In Flask you don't - have to deal with that at all, the underlying Werkzeug library handles - that for you. - -`POST` - The browser tells the server that it wants to *post* some new - information to that URL and that the server must ensure the data is - stored and only stored once. This is how HTML forms are usually - transmitting data to the server. - -`PUT` - Similar to `POST` but the server might trigger the store procedure - multiple times by overwriting the old values more than once. Now you - might be asking why is this useful, but there are some good reasons - to do it this way. Consider that the connection gets lost during - transmission: in this situation a system between the browser and the - server might receive the request safely a second time without breaking - things. With `POST` that would not be possible because it must only - be triggered once. - -`DELETE` - Remove the information at the given location. - -`OPTIONS` - Provides a quick way for a client to figure out which methods are - supported by this URL. Starting with Flask 0.6, this is implemented - for you automatically. - -Now the interesting part is that in HTML4 and XHTML1, the only methods a -form can submit to the server are `GET` and `POST`. But with JavaScript -and future HTML standards you can use the other methods as well. Furthermore -HTTP has become quite popular lately and browsers are no longer the only -clients that are using HTTP. For instance, many revision control system -use it. - -.. _HTTP RFC: http://www.ietf.org/rfc/rfc2068.txt - -Static Files ------------- - -Dynamic web applications need static files as well. That's usually where -the CSS and JavaScript files are coming from. Ideally your web server is -configured to serve them for you, but during development Flask can do that -as well. Just create a folder called `static` in your package or next to -your module and it will be available at `/static` on the application. - -To generate URLs to that part of the URL, use the special ``'static'`` URL -name:: - - url_for('static', filename='style.css') - -The file has to be stored on the filesystem as ``static/style.css``. - -Rendering Templates -------------------- - -Generating HTML from within Python is not fun, and actually pretty -cumbersome because you have to do the HTML escaping on your own to keep -the application secure. Because of that Flask configures the `Jinja2 -<http://jinja.pocoo.org/2/>`_ template engine for you automatically. - -To render a template you can use the :func:`~flask.render_template` -method. All you have to do is to provide the name of the template and the -variables you want to pass to the template engine as keyword arguments. -Here's a simple example of how to render a template:: - - from flask import render_template - - @app.route('/hello/') - @app.route('/hello/<name>') - def hello(name=None): - return render_template('hello.html', name=name) - -Flask will look for templates in the `templates` folder. So if your -application is a module, that folder is next to that module, if it's a -package it's actually inside your package: - -**Case 1**: a module:: - - /application.py - /templates - /hello.html - -**Case 2**: a package:: - - /application - /__init__.py - /templates - /hello.html - -For templates you can use the full power of Jinja2 templates. Head over -to the the official `Jinja2 Template Documentation -<http://jinja.pocoo.org/2/documentation/templates>`_ for more information. - -Here is an example template: - -.. sourcecode:: html+jinja - - <!doctype html> - <title>Hello from Flask</title> - {% if name %} - <h1>Hello {{ name }}!</h1> - {% else %} - <h1>Hello World!</h1> - {% endif %} - -Inside templates you also have access to the :class:`~flask.request`, -:class:`~flask.session` and :class:`~flask.g` [#]_ objects -as well as the :func:`~flask.get_flashed_messages` function. - -Templates are especially useful if inheritance is used. If you want to -know how that works, head over to the :ref:`template-inheritance` pattern -documentation. Basically template inheritance makes it possible to keep -certain elements on each page (like header, navigation and footer). - -Automatic escaping is enabled, so if name contains HTML it will be escaped -automatically. If you can trust a variable and you know that it will be -safe HTML (because for example it came from a module that converts wiki -markup to HTML) you can mark it as safe by using the -:class:`~jinja2.Markup` class or by using the ``|safe`` filter in the -template. Head over to the Jinja 2 documentation for more examples. - -Here is a basic introduction to how the :class:`~jinja2.Markup` class works: - ->>> from flask import Markup ->>> Markup('<strong>Hello %s!</strong>') % '<blink>hacker</blink>' -Markup(u'<strong>Hello <blink>hacker</blink>!</strong>') ->>> Markup.escape('<blink>hacker</blink>') -Markup(u'<blink>hacker</blink>') ->>> Markup('<em>Marked up</em> » HTML').striptags() -u'Marked up \xbb HTML' - -.. versionchanged:: 0.5 - - Autoescaping is no longer enabled for all templates. The following - extensions for templates trigger autoescaping: ``.html``, ``.htm``, - ``.xml``, ``.xhtml``. Templates loaded from a string will have - autoescaping disabled. - -.. [#] Unsure what that :class:`~flask.g` object is? It's something in which - you can store information for your own needs, check the documentation of - that object (:class:`~flask.g`) and the :ref:`sqlite3` for more - information. - - -Accessing Request Data ----------------------- - -For web applications it's crucial to react to the data a client sent 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 are context locals: - - -.. _context-locals: - -Context Locals -`````````````` - -.. admonition:: 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 -webserver decides to spawn a new thread (or something else, the -underlying object is capable of dealing with other concurrency systems -than threads as well). 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 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 unittesting. You -will notice that code that 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 -unittesting is by using 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' - # this is executed if the request method was GET or the - # credentials were invalid - -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('q', '') - -We recommend accessing URL parameters with `get` or by catching the -`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 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 you -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`. - -Redirects and Errors --------------------- - -To redirect a user to somewhere else you can use the -:func:`~flask.redirect` function. To abort a request early with an error -code use the :func:`~flask.abort` function. Here an example how this works:: - - from flask import abort, redirect, url_for - - @app.route('/') - def index(): - return redirect(url_for('login')) - - @app.route('/login') - def login(): - abort(401) - this_is_never_executed() - -This is a rather pointless example because a user will be redirected from -the index to a page they cannot access (401 means access denied) but it -shows how that works. - -By default a black and white error page is shown for each error code. If -you want to customize the error page, you can use the -:meth:`~flask.Flask.errorhandler` decorator:: - - from flask import render_template - - @app.errorhandler(404) - def page_not_found(error): - return render_template('page_not_found.html'), 404 - -Note the ``404`` after the :func:`~flask.render_template` call. This -tells Flask that the status code of that page should be 404 which means -not found. By default 200 is assumed which translates to: all went well. - -.. _about-responses: - -About Responses ---------------- - -The return value from a view function is automatically converted into a -response object for you. If the return value is a string it's converted -into a response object with the string as response body, an ``200 OK`` -error code and a ``text/html`` mimetype. The logic that Flask applies to -converting return values into response objects is as follows: - -1. If a response object of the correct type is returned it's directly - returned from the view. -2. If it's a string, a response object is created with that data and the - default parameters. -3. If a tuple is returned the response object is created by passing the - tuple as arguments to the response object's constructor. -4. If neither of that works, Flask will assume the return value is a - valid WSGI application and converts that into a response object. - -If you want to get hold of the resulting response object inside the view -you can use the :func:`~flask.make_response` function. - -Imagine you have a view like this: - -.. sourcecode:: python - - @app.errorhandler(404) - def not_found(error): - return render_template('error.html'), 404 - -You just need to wrap the return expression with -:func:`~flask.make_response` and get the result object to modify it, then -return it: - -.. sourcecode:: python - - @app.errorhandler(404) - def not_found(error): - resp = make_response(render_template('error.html'), 404) - resp.headers['X-Something'] = 'A value' - return resp - -.. _sessions: - -Sessions --------- - -Besides the request object there is also a second object called -:class:`~flask.session` that allows you to store information specific to a -user from one request to the next. This is implemented on top of cookies -for you and signs the cookies cryptographically. What this means is that -the user could look at the contents of your cookie but not modify it, -unless they know the secret key used for signing. - -In order to use sessions you have to set a secret key. Here is how -sessions work:: - - from flask import Flask, session, redirect, url_for, escape, request - - app = Flask(__name__) - - @app.route('/') - def index(): - if 'username' in session: - return 'Logged in as %s' % escape(session['username']) - return 'You are not logged in' - - @app.route('/login', methods=['GET', 'POST']) - def login(): - if request.method == 'POST': - session['username'] = request.form['username'] - return redirect(url_for('index')) - return ''' - <form action="" method="post"> - <p><input type=text name=username> - <p><input type=submit value=Login> - </form> - ''' - - @app.route('/logout') - def logout(): - # remove the username from the session if its there - session.pop('username', None) - return redirect(url_for('index')) - - # set the secret key. keep this really secret: - app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT' - -The here mentioned :func:`~flask.escape` does escaping for you if you are -not using the template engine (like in this example). - -.. admonition:: How to generate good secret keys - - The problem with random is that it's hard to judge what random is. And - a secret key should be as random as possible. Your operating system - has ways to generate pretty random stuff based on a cryptographic - random generator which can be used to get such a key: - - >>> import os - >>> os.urandom(24) - '\xfd{H\xe5<\x95\xf9\xe3\x96.5\xd1\x01O<!\xd5\xa2\xa0\x9fR"\xa1\xa8' - - Just take that thing and copy/paste it into your code and you're done. - -Message Flashing ----------------- - -Good applications and user interfaces are all about feedback. If the user -does not get enough feedback they will probably end up hating the -application. Flask provides a really simple way to give feedback to a -user with the flashing system. The flashing system basically makes it -possible to record a message at the end of a request and access it next -request and only next request. This is usually combined with a layout -template that does this. - -To flash a message use the :func:`~flask.flash` method, to get hold of the -messages you can use :func:`~flask.get_flashed_messages` which is also -available in the templates. Check out the :ref:`message-flashing-pattern` -for a full example. - -Logging -------- - -.. versionadded:: 0.3 - -Sometimes you might be in a situation where you deal with data that -should be correct, but actually is not. For example you may have some client -side code that sends an HTTP request to the server but it's obviously -malformed. This might be caused by a user tempering with the data, or the -client code failing. Most of the time, it's okay to reply with ``400 Bad -Request`` in that situation, but sometimes that won't do and the code has -to continue working. - -You may still want to log that something fishy happened. This is where -loggers come in handy. As of Flask 0.3 a logger is preconfigured for you -to use. - -Here are some example log calls:: - - app.logger.debug('A value for debugging') - app.logger.warning('A warning occurred (%d apples)', 42) - app.logger.error('An error occurred') - -The attached :attr:`~flask.Flask.logger` is a standard logging -:class:`~logging.Logger`, so head over to the official `logging -documentation <http://docs.python.org/library/logging.html>`_ for more -information. - -Hooking in WSGI Middlewares ---------------------------- - -If you want to add a WSGI middleware to your application you can wrap the -internal WSGI application. For example if you want to use one of the -middlewares from the Werkzeug package to work around bugs in lighttpd, you -can do it like this:: - - from werkzeug.contrib.fixers import LighttpdCGIRootFix - app.wsgi_app = LighttpdCGIRootFix(app.wsgi_app) |