1Deploying with Setuptools
2=========================
3
4`Setuptools`_, is an extension library that is commonly used to
5distribute Python libraries and extensions. It extends distutils, a basic
6module installation system shipped with Python to also support various more
7complex constructs that make larger applications easier to distribute:
8
9- **support for dependencies**: a library or application can declare a
10  list of other libraries it depends on which will be installed
11  automatically for you.
12- **package registry**: setuptools registers your package with your
13  Python installation.  This makes it possible to query information
14  provided by one package from another package.  The best known feature of
15  this system is the entry point support which allows one package to
16  declare an "entry point" that another package can hook into to extend the
17  other package.
18- **installation manager**: :command:`pip` can install other libraries for you.
19
20Flask itself, and all the libraries you can find on PyPI are distributed with
21either setuptools or distutils.
22
23In this case we assume your application is called
24:file:`yourapplication.py` and you are not using a module, but a
25package. If you have not yet converted your application into a package,
26head over to :doc:`packages` to see how this can be done.
27
28A working deployment with setuptools is the first step into more complex
29and more automated deployment scenarios.  If you want to fully automate
30the process, also read the :doc:`fabric` chapter.
31
32Basic Setup Script
33------------------
34
35Because you have Flask installed, you have setuptools available on your system.
36Flask already depends upon setuptools.
37
38Standard disclaimer applies: :ref:`use a virtualenv
39<install-create-env>`.
40
41Your setup code always goes into a file named :file:`setup.py` next to your
42application.  The name of the file is only convention, but because
43everybody will look for a file with that name, you better not change it.
44
45A basic :file:`setup.py` file for a Flask application looks like this::
46
47    from setuptools import setup
48
49    setup(
50        name='Your Application',
51        version='1.0',
52        long_description=__doc__,
53        packages=['yourapplication'],
54        include_package_data=True,
55        zip_safe=False,
56        install_requires=['Flask']
57    )
58
59Please keep in mind that you have to list subpackages explicitly.  If you
60want setuptools to lookup the packages for you automatically, you can use
61the ``find_packages`` function::
62
63    from setuptools import setup, find_packages
64
65    setup(
66        ...
67        packages=find_packages()
68    )
69
70Most parameters to the ``setup`` function should be self explanatory,
71``include_package_data`` and ``zip_safe`` might not be.
72``include_package_data`` tells setuptools to look for a :file:`MANIFEST.in` file
73and install all the entries that match as package data.  We will use this
74to distribute the static files and templates along with the Python module
75(see :ref:`distributing-resources`).  The ``zip_safe`` flag can be used to
76force or prevent zip Archive creation.  In general you probably don't want
77your packages to be installed as zip files because some tools do not
78support them and they make debugging a lot harder.
79
80
81Tagging Builds
82--------------
83
84It is useful to distinguish between release and development builds. Add a
85:file:`setup.cfg` file to configure these options. ::
86
87    [egg_info]
88    tag_build = .dev
89    tag_date = 1
90
91    [aliases]
92    release = egg_info -Db ''
93
94Running ``python setup.py sdist`` will create a development package
95with ".dev" and the current date appended: ``flaskr-1.0.dev20160314.tar.gz``.
96Running ``python setup.py release sdist`` will create a release package
97with only the version: ``flaskr-1.0.tar.gz``.
98
99
100.. _distributing-resources:
101
102Distributing Resources
103----------------------
104
105If you try to install the package you just created, you will notice that
106folders like :file:`static` or :file:`templates` are not installed for you.  The
107reason for this is that setuptools does not know which files to add for
108you.  What you should do, is to create a :file:`MANIFEST.in` file next to your
109:file:`setup.py` file.  This file lists all the files that should be added to
110your tarball::
111
112    recursive-include yourapplication/templates *
113    recursive-include yourapplication/static *
114
115Don't forget that even if you enlist them in your :file:`MANIFEST.in` file, they
116won't be installed for you unless you set the `include_package_data`
117parameter of the ``setup`` function to ``True``!
118
119
120Declaring Dependencies
121----------------------
122
123Dependencies are declared in the ``install_requires`` parameter as a list.
124Each item in that list is the name of a package that should be pulled from
125PyPI on installation.  By default it will always use the most recent
126version, but you can also provide minimum and maximum version
127requirements.  Here some examples::
128
129    install_requires=[
130        'Flask>=0.2',
131        'SQLAlchemy>=0.6',
132        'BrokenPackage>=0.7,<=1.0'
133    ]
134
135As mentioned earlier, dependencies are pulled from PyPI.  What if you
136want to depend on a package that cannot be found on PyPI and won't be
137because it is an internal package you don't want to share with anyone?
138Just do it as if there was a PyPI entry and provide a list of
139alternative locations where setuptools should look for tarballs::
140
141    dependency_links=['http://example.com/yourfiles']
142
143Make sure that page has a directory listing and the links on the page are
144pointing to the actual tarballs with their correct filenames as this is
145how setuptools will find the files.  If you have an internal company
146server that contains the packages, provide the URL to that server.
147
148
149Installing / Developing
150-----------------------
151
152To install your application (ideally into a virtualenv) just run the
153:file:`setup.py` script with the ``install`` parameter.  It will install your
154application into the virtualenv's site-packages folder and also download
155and install all dependencies::
156
157    $ python setup.py install
158
159If you are developing on the package and also want the requirements to be
160installed, you can use the ``develop`` command instead::
161
162    $ python setup.py develop
163
164This has the advantage of just installing a link to the site-packages
165folder instead of copying the data over.  You can then continue to work on
166the code without having to run ``install`` again after each change.
167
168
169.. _pip: https://pypi.org/project/pip/
170.. _Setuptools: https://pypi.org/project/setuptools/
171