From 576efe8faea4d79bd7d883d166e51b19a2cdfc9d Mon Sep 17 00:00:00 2001 From: David Lord Date: Fri, 5 Aug 2022 11:08:54 -0700 Subject: [PATCH] remove distribute and fabric patterns --- docs/config.rst | 16 ++- docs/patterns/distribute.rst | 170 -------------------------------- docs/patterns/fabric.rst | 184 ----------------------------------- docs/patterns/index.rst | 2 - 4 files changed, 6 insertions(+), 366 deletions(-) delete mode 100644 docs/patterns/distribute.rst delete mode 100644 docs/patterns/fabric.rst diff --git a/docs/config.rst b/docs/config.rst index bc16e4ba..bdcbdcd4 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -394,13 +394,11 @@ The following configuration values are used internally by Flask: Configuring from Python Files ----------------------------- -Configuration becomes more useful if you can store it in a separate file, -ideally located outside the actual application package. This makes -packaging and distributing your application possible via various package -handling tools (:doc:`/patterns/distribute`) and finally modifying the -configuration file afterwards. +Configuration becomes more useful if you can store it in a separate file, ideally +located outside the actual application package. You can deploy your application, then +separately configure it for the specific deployment. -So a common pattern is this:: +A common pattern is this:: app = Flask(__name__) app.config.from_object('yourapplication.default_settings') @@ -692,10 +690,8 @@ your configuration files. However here a list of good recommendations: code at all. If you are working often on different projects you can even create your own script for sourcing that activates a virtualenv and exports the development configuration for you. -- Use a tool like `fabric`_ in production to push code and - configurations separately to the production server(s). For some - details about how to do that, head over to the - :doc:`/patterns/fabric` pattern. +- Use a tool like `fabric`_ to push code and configuration separately + to the production server(s). .. _fabric: https://www.fabfile.org/ diff --git a/docs/patterns/distribute.rst b/docs/patterns/distribute.rst deleted file mode 100644 index 83885df7..00000000 --- a/docs/patterns/distribute.rst +++ /dev/null @@ -1,170 +0,0 @@ -Deploying with Setuptools -========================= - -`Setuptools`_, is an extension library that is commonly used to -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" that another package can hook into to extend the - other package. -- **installation manager**: :command:`pip` can install other libraries for you. - -Flask itself, and all the libraries you can find on PyPI are distributed with -either setuptools or distutils. - -In this case we assume your application is called -:file:`yourapplication.py` and you are not using a module, but a -package. If you have not yet converted your application into a package, -head over to :doc:`packages` to see how this can be done. - -A working deployment with setuptools is the first step into more complex -and more automated deployment scenarios. If you want to fully automate -the process, also read the :doc:`fabric` chapter. - -Basic Setup Script ------------------- - -Because you have Flask installed, you have setuptools available on your system. -Flask already depends upon setuptools. - -Standard disclaimer applies: :ref:`use a virtualenv -`. - -Your setup code always goes into a file named :file:`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. - -A basic :file:`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 setuptools 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 setuptools to look for a :file:`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. - - -Tagging Builds --------------- - -It is useful to distinguish between release and development builds. Add a -:file:`setup.cfg` file to configure these options. :: - - [egg_info] - tag_build = .dev - tag_date = 1 - - [aliases] - release = egg_info -Db '' - -Running ``python setup.py sdist`` will create a development package -with ".dev" and the current date appended: ``flaskr-1.0.dev20160314.tar.gz``. -Running ``python setup.py release sdist`` will create a release package -with only the version: ``flaskr-1.0.tar.gz``. - - -.. _distributing-resources: - -Distributing Resources ----------------------- - -If you try to install the package you just created, you will notice that -folders like :file:`static` or :file:`templates` are not installed for you. The -reason for this is that setuptools does not know which files to add for -you. What you should do, is to create a :file:`MANIFEST.in` file next to your -:file:`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 :file:`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 a 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' - ] - -As mentioned earlier, 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 do it as if there was a PyPI entry and provide a list of -alternative locations where setuptools 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 setuptools will find the files. If you have an internal company -server that contains the packages, provide the URL to that server. - - -Installing / Developing ------------------------ - -To install your application (ideally into a virtualenv) just run the -:file:`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. - - -.. _pip: https://pypi.org/project/pip/ -.. _Setuptools: https://pypi.org/project/setuptools/ diff --git a/docs/patterns/fabric.rst b/docs/patterns/fabric.rst deleted file mode 100644 index 0cd39ddc..00000000 --- a/docs/patterns/fabric.rst +++ /dev/null @@ -1,184 +0,0 @@ -Deploying with Fabric -===================== - -`Fabric`_ is a tool for Python similar to Makefiles but with the ability -to execute commands on a remote server. In combination with a properly -set up Python package (:doc:`packages`) and a good concept for -configurations (:doc:`/config`) it is very easy to deploy Flask -applications to external servers. - -Before we get started, here a quick checklist of things we have to ensure -upfront: - -- Fabric 1.0 has to be installed locally. This tutorial assumes the - latest version of Fabric. -- The application already has to be a package and requires a working - :file:`setup.py` file (:doc:`distribute`). -- In the following example we are using `mod_wsgi` for the remote - servers. You can of course use your own favourite server there, but - for this example we chose Apache + `mod_wsgi` because it's very easy - to setup and has a simple way to reload applications without root - access. - -Creating the first Fabfile --------------------------- - -A fabfile is what controls what Fabric executes. It is named :file:`fabfile.py` -and executed by the `fab` command. All the functions defined in that file -will show up as `fab` subcommands. They are executed on one or more -hosts. These hosts can be defined either in the fabfile or on the command -line. In this case we will add them to the fabfile. - -This is a basic first example that has the ability to upload the current -source code to the server and install it into a pre-existing -virtual environment:: - - from fabric.api import * - - # the user to use for the remote commands - env.user = 'appuser' - # the servers where the commands are executed - env.hosts = ['server1.example.com', 'server2.example.com'] - - def pack(): - # build the package - local('python setup.py sdist --formats=gztar', capture=False) - - def deploy(): - # figure out the package name and version - dist = local('python setup.py --fullname', capture=True).strip() - filename = f'{dist}.tar.gz' - - # upload the package to the temporary folder on the server - put(f'dist/{filename}', f'/tmp/{filename}') - - # install the package in the application's virtualenv with pip - run(f'/var/www/yourapplication/env/bin/pip install /tmp/{filename}') - - # remove the uploaded package - run(f'rm -r /tmp/{filename}') - - # touch the .wsgi file to trigger a reload in mod_wsgi - run('touch /var/www/yourapplication.wsgi') - -Running Fabfiles ----------------- - -Now how do you execute that fabfile? You use the `fab` command. To -deploy the current version of the code on the remote server you would use -this command:: - - $ fab pack deploy - -However this requires that our server already has the -:file:`/var/www/yourapplication` folder created and -:file:`/var/www/yourapplication/env` to be a virtual environment. Furthermore -are we not creating the configuration or ``.wsgi`` file on the server. So -how do we bootstrap a new server into our infrastructure? - -This now depends on the number of servers we want to set up. If we just -have one application server (which the majority of applications will -have), creating a command in the fabfile for this is overkill. But -obviously you can do that. In that case you would probably call it -`setup` or `bootstrap` and then pass the servername explicitly on the -command line:: - - $ fab -H newserver.example.com bootstrap - -To setup a new server you would roughly do these steps: - -1. Create the directory structure in :file:`/var/www`:: - - $ mkdir /var/www/yourapplication - $ cd /var/www/yourapplication - $ virtualenv --distribute env - -2. Upload a new :file:`application.wsgi` file to the server and the - configuration file for the application (eg: :file:`application.cfg`) - -3. Create a new Apache config for ``yourapplication`` and activate it. - Make sure to activate watching for changes of the ``.wsgi`` file so - that we can automatically reload the application by touching it. - See :doc:`/deploying/mod_wsgi`. - -So now the question is, where do the :file:`application.wsgi` and -:file:`application.cfg` files come from? - -The WSGI File -------------- - -The WSGI file has to import the application and also to set an environment -variable so that the application knows where to look for the config. This -is a short example that does exactly that:: - - import os - os.environ['YOURAPPLICATION_CONFIG'] = '/var/www/yourapplication/application.cfg' - from yourapplication import app - -The application itself then has to initialize itself like this to look for -the config at that environment variable:: - - app = Flask(__name__) - app.config.from_object('yourapplication.default_config') - app.config.from_envvar('YOURAPPLICATION_CONFIG') - -This approach is explained in detail in the :doc:`/config` section of the -documentation. - -The Configuration File ----------------------- - -Now as mentioned above, the application will find the correct -configuration file by looking up the ``YOURAPPLICATION_CONFIG`` environment -variable. So we have to put the configuration in a place where the -application will able to find it. Configuration files have the unfriendly -quality of being different on all computers, so you do not version them -usually. - -A popular approach is to store configuration files for different servers -in a separate version control repository and check them out on all -servers. Then symlink the file that is active for the server into the -location where it's expected (eg: :file:`/var/www/yourapplication`). - -Either way, in our case here we only expect one or two servers and we can -upload them ahead of time by hand. - - -First Deployment ----------------- - -Now we can do our first deployment. We have set up the servers so that -they have their virtual environments and activated apache configs. Now we -can pack up the application and deploy it:: - - $ fab pack deploy - -Fabric will now connect to all servers and run the commands as written -down in the fabfile. First it will execute pack so that we have our -tarball ready and then it will execute deploy and upload the source code -to all servers and install it there. Thanks to the :file:`setup.py` file we -will automatically pull in the required libraries into our virtual -environment. - -Next Steps ----------- - -From that point onwards there is so much that can be done to make -deployment actually fun: - -- Create a `bootstrap` command that initializes new servers. It could - initialize a new virtual environment, setup apache appropriately etc. -- Put configuration files into a separate version control repository - and symlink the active configs into place. -- You could also put your application code into a repository and check - out the latest version on the server and then install. That way you - can also easily go back to older versions. -- hook in testing functionality so that you can deploy to an external - server and run the test suite. - -Working with Fabric is fun and you will notice that it's quite magical to -type ``fab deploy`` and see your application being deployed automatically -to one or more remote servers. - - -.. _Fabric: https://www.fabfile.org/ diff --git a/docs/patterns/index.rst b/docs/patterns/index.rst index d7338ac0..1f2c07dd 100644 --- a/docs/patterns/index.rst +++ b/docs/patterns/index.rst @@ -19,8 +19,6 @@ collected in the following pages. appfactories appdispatch urlprocessors - distribute - fabric sqlite3 sqlalchemy fileuploads