From 931dcc4c80331d372d70d7a0a5c8e6d49223e2bf Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Mon, 17 May 2010 01:41:57 +0200 Subject: [PATCH] Fixed a doc bug and added distribtue docs. --- docs/installation.rst | 2 + docs/patterns/distribute.rst | 160 +++++++++++++++++++++++++++++++++++ docs/patterns/flashing.rst | 38 +++++++++ docs/patterns/index.rst | 1 + flask.py | 2 +- 5 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 docs/patterns/distribute.rst diff --git a/docs/installation.rst b/docs/installation.rst index deedb12b..6b4f955a 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -19,6 +19,8 @@ lighttpd, on Google's App Engine or whatever you have in mind). So how do you get all that on your computer in no time? The most kick-ass method is virtualenv, so let's look at that first. +.. _virtualenv: + virtualenv ---------- diff --git a/docs/patterns/distribute.rst b/docs/patterns/distribute.rst new file mode 100644 index 00000000..c4f6625d --- /dev/null +++ b/docs/patterns/distribute.rst @@ -0,0 +1,160 @@ +Deploying with Distribute +========================= + +`distribute`_, formerly setuptools, is an extension library that is +commonly used to (like the name says) distribute Python libraries and +extensions. It extends distutils, a basic module installation system +shipped with Python to also support various more complex constructs that +make larger applications easier to distribute: + +- **support for dependencies**: a library or application can declare a + list of other libraries it depends on which will be installed + automatically for you. +- **package registry**: setuptools registers your package with your + Python installation. This makes it possible to query information + provided by one package from another package. The best known feature of + this system is the entry point support which allows one package to + declare an "entry point" another package can hook into to extend the + other package. +- **installation manager**: `easy_install`, which comes with distribute + can install other libraries for you. You can also use `pip`_ which + sooner or later will replace `easy_install` which does more than just + installing packages for you. + +Flask itself, and all the libraries you can find on the cheeseshop will +are distributed with either distribute, the older setuptools or distutils. + +In this case we assume your application is called +`yourapplication.py` and you are not using a module, but a `package +`_. Distributing resources with standard modules is +not supported by `distribute`_ so we will not bother with it. If you have +not yet converted your application into a package, head over to the +:ref:`larger-applications` pattern to see how this can be done. + +Basic Setup Script +------------------ + +Because you have Flask running, you either have setuptools or distribute +available on your system anyways. If you do not, fear not, there is a +script to install it for you: `distribute_setup.py`_. Just download and +run with your Python interpreter. + +Standard disclaimer applies: :ref:`you better use a virtualenv +`. + +Your setup code always goes into a file named `setup.py` next to your +application. The name of the file is only convention, but because +everybody will look for a file with that name, you better not change it. + +Yes, even if you are using `distribute`, you are importing from a package +called `setuptools`. `distribute` is fully backwards compatible with +`setuptools`, so it also uses the same import name. + +A basic `setup.py` file for a Flask application looks like this:: + + from setuptools import setup + + setup( + name='Your Application', + version='1.0', + long_description=__doc__, + packages=['yourapplication'], + include_package_data=True, + zip_safe=False, + install_requires=['Flask'] + ) + +Please keep in mind that you have to list subpackages explicitly. If you +want distribute to lookup the packages for you automatically, you can use +the `find_packages` function:: + + from setuptools import setup, find_packages + + setup( + ... + packages=find_packages() + ) + +Most parameters to the `setup` function should be self explanatory, +`include_package_data` and `zip_safe` might not be. +`include_package_data` tells distribute to look for a `MANIFEST.in` file +and install all the entries that match as package data. We will use this +to distribute the static files and templates along with the Python module +(see :ref:`distributing-resources`). The `zip_safe` flag can be used to +force or prevent zip Archive creation. In general you probably don't want +your packages to be installed as zip files because some tools do not +support them and they make debugging a lot harder. + + +.. _distributing-resources: + +Distributing Resources +---------------------- + +If you try to install the package you just created, you will notice that +folders like `static` or `templates` are not installed for you. The +reason for this is that distribute does not know which files to add for +you. What you should do, is to create a `MANIFEST.in` file next to your +`setup.py` file. This file lists all the files that should be added to +your tarball:: + + recursive-include yourapplication/templates + recursive-include yourapplication/static + +Don't forget that even if you enlist them in your `MANIFEST.in` file, they +won't be installed for you unless you set the `include_package_data` +parameter of the `setup` function to `True`! + + +Declaring Dependencies +---------------------- + +Dependencies are declared in the `install_requires` parameter as list. +Each item in that list is the name of a package that should be pulled from +PyPI on installation. By default it will always use the most recent +version, but you can also provide minimum and maximum version +requirements. Here some examples:: + + install_requires=[ + 'Flask>=0.2', + 'SQLAlchemy>=0.6', + 'BrokenPackage>=0.7,<=1.0' + ] + +I mentioned earlier that dependencies are pulled from PyPI. What if you +want to depend on a package that cannot be found on PyPI and won't be +because it is an internal package you don't want to share with anyone? +Just still do as if there was a PyPI entry for it and provide a list of +alternative locations where distribute should look for tarballs:: + + dependency_links=['http://example.com/yourfiles'] + +Make sure that page has a directory listing and the links on the page are +pointing to the actual tarballs with their correct filenames as this is +how distribute will find the files. If you have an internal company +server that contains the packages, provide the URL to that server there. + + +Installing / Developing +----------------------- + +To install your application (ideally into a virtualenv) just run the +`setup.py` script with the `install` parameter. It will install your +application into the virtualenv's site-packages folder and also download +and install all dependencies:: + + $ python setup.py install + +If you are developing on the package and also want the requirements to be +installed, you can use the `develop` command instead:: + + $ python setup.py develop + +This has the advantage of just installing a link to the site-packages +folder instead of copying the data over. You can then continue to work on +the code without having to run `install` again after each change. + + +.. _distribute: http://pypi.python.org/pypi/distribute +.. _pip: http://pypi.python.org/pypi/pip +.. _distribute_setup.py: http://python-distribute.org/distribute_setup.py diff --git a/docs/patterns/flashing.rst b/docs/patterns/flashing.rst index fca9a9e1..16d8d371 100644 --- a/docs/patterns/flashing.rst +++ b/docs/patterns/flashing.rst @@ -11,6 +11,9 @@ 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. +Simple Flashing +--------------- + So here a full example:: from flask import flash, redirect, url_for, render_template @@ -79,3 +82,38 @@ And of course the login template:

{% endblock %} + +Flashing With Categories +------------------------ + +.. versionadded:: 0.5 + +It is also possible to provide categories when flashing a message. The +default category if nothing is provided is ``'message'``. Alternative +categories can be used to give the user better feedback. For example +error messages could be displayed with a red background. + +To flash a message with a different category, just use the second argument +to the :func:`~flask.flash` function:: + + flash(u'Invalid password provided', 'error') + +Inside the template you then have to tell the +:func:`~flask.get_flashed_messages` function to also return the +categories. The loop looks slighty different in that situation then: + +.. sourcecode:: html+jinja + + {% with messages = get_flashed_messages(with_categories=true) %} + {% if messages %} +

    + {% for category, message in messages %} +
  • {{ message }}
  • + {% endfor %} +
+ {% endif %} + {% endwith %} + +This is just one example of how to render these flashed messages. One +might also use the category to add a prefix such as +``Error:`` to the message. diff --git a/docs/patterns/index.rst b/docs/patterns/index.rst index 9678e3be..ec3011f6 100644 --- a/docs/patterns/index.rst +++ b/docs/patterns/index.rst @@ -17,6 +17,7 @@ Snippet Archives `_. :maxdepth: 2 packages + distribute sqlite3 sqlalchemy fileuploads diff --git a/flask.py b/flask.py index d745027d..6fa3f7e3 100644 --- a/flask.py +++ b/flask.py @@ -230,7 +230,7 @@ def flash(message, category='message'): are recommended: ``'message'`` for any kind of message, ``'error'`` for errors, ``'info'`` for information messages and ``'warning'`` for warnings. However any - kind of string and be used as category. + kind of string can be used as category. """ session.setdefault('_flashes', []).append((category, message))