Skip to content

Commit

Permalink
Update documentation for constraints installation (#31882)
Browse files Browse the repository at this point in the history
* Update documentation for constraints installation

Airlow constraints and custom depenencies are a mystery for our
users. The reason why we are using constraints is not clear and
user are confused when they should and when they shoudl not use
constraints. Recent discussions with users and "Mastering Custom
Dependencies" presentation in London has proven that we need to
do better and simplify the documentation while giving more, better
examples. That includes trimming down of boilerplate description
in the constraint information, explaining a little more on what
reproducibke (not repeatable!) build is, adding expectation that
users will not use constraints for all pip commands and explaining
how to produce your own constraints if you need a reproducible,
custom build.

This PR aims to fulfill those goals.

* Update docs/apache-airflow/installation/installing-from-pypi.rst

Co-authored-by: Jed Cunningham <66968678+jedcunningham@users.noreply.github.com>

* Update docs/apache-airflow/installation/installing-from-pypi.rst

* Update docs/apache-airflow/installation/installing-from-pypi.rst

* fixup! Update docs/apache-airflow/installation/installing-from-pypi.rst

* Update docs/apache-airflow/installation/installing-from-pypi.rst

Co-authored-by: Pankaj Koti <pankajkoti699@gmail.com>

* Update docs/apache-airflow/installation/installing-from-pypi.rst

Co-authored-by: Pankaj Koti <pankajkoti699@gmail.com>

* Update docs/apache-airflow/installation/installing-from-pypi.rst

Co-authored-by: Pankaj Koti <pankajkoti699@gmail.com>

* Update docs/apache-airflow/installation/installing-from-pypi.rst

Co-authored-by: Pankaj Koti <pankajkoti699@gmail.com>

* Update docs/apache-airflow/installation/installing-from-pypi.rst

Co-authored-by: Pankaj Koti <pankajkoti699@gmail.com>

* Update docs/apache-airflow/installation/installing-from-pypi.rst

Co-authored-by: Pankaj Koti <pankajkoti699@gmail.com>

* fixup! Update docs/apache-airflow/installation/installing-from-pypi.rst

---------

Co-authored-by: Jed Cunningham <66968678+jedcunningham@users.noreply.github.com>
Co-authored-by: Pankaj Koti <pankajkoti699@gmail.com>
(cherry picked from commit f8f0cbc)
  • Loading branch information
potiuk authored and pierrejeambrun committed Jun 14, 2023
1 parent bde7800 commit 4cb0536
Showing 1 changed file with 185 additions and 69 deletions.
254 changes: 185 additions & 69 deletions docs/apache-airflow/installation/installing-from-pypi.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,33 +33,65 @@ Installing via ``Poetry`` or ``pip-tools`` is not currently supported. If you wi
using those tools you should use the constraints and convert them to appropriate
format and workflow that your tool requires.

Typical command to install airflow from PyPI looks like below:
Typical command to install airflow from scratch in a reproducible way from PyPI looks like below:

.. code-block::
.. code-block:: bash
pip install "apache-airflow[celery]==|version|" --constraint "https://raw.githubusercontent.com/apache/airflow/constraints-|version|/constraints-3.7.txt"
This is an example, see further for more explanation.
Typically, you can add other dependencies and providers as separate command after the reproducible
installation - this way you can upgrade or downgrade the dependencies as you see fit, without limiting them to
constraints. Good practice for those is to extend such ``pip install`` command with the ``apache-airflow``
pinned to the version you have already installed to make sure it is not accidentally
upgraded or downgraded by ``pip``.

.. code-block:: bash
pip install "apache-airflow==|version|" apache-airflow-providers-google==10.1.0
Those are just examples, see further for more explanation why those are the best practices.

.. note::

Generally speaking, Python community established practice is to perform application installation in a
virtualenv created with ``virtualenv`` or ``venv`` tools. You can also use ``pipx`` to install Airflow in a
application dedicated virtual environment created for you. There are also other tools that can be used
to manage your virtualenv installation and you are free to choose how you are managing the environments.
Airflow has no limitation regarding to the tool of your choice when it comes to virtual environment.

The only exception where you might consider not using virtualenv is when you are building a container
image with only Airflow installed - this is for example how Airflow is installed in the official Container
image.

.. _installation:constraints:

Constraints files
'''''''''''''''''

Airflow installation can be tricky sometimes because Airflow is both a library and an application.
Why we need constraints
=======================

Airflow installation can be tricky because Airflow is both a library and an application.

Libraries usually keep their dependencies open and applications usually pin them, but we should do neither
and both at the same time. We decided to keep our dependencies as open as possible
(in ``setup.cfg`` and ``setup.py``) so users can install different
version of libraries if needed. This means that from time to time plain ``pip install apache-airflow`` will
not work or will produce an unusable Airflow installation.

In order to have a repeatable installation (and only for that reason), we also keep a set of "known-to-be-working" constraint files in the
Reproducible Airflow installation
=================================

In order to have a reproducible installation, we also keep a set of constraint files in the
``constraints-main``, ``constraints-2-0``, ``constraints-2-1`` etc. orphan branches and then we create a tag
for each released version e.g. :subst-code:`constraints-|version|`. This way, we keep a tested and working set of dependencies.
for each released version e.g. :subst-code:`constraints-|version|`.

Those "known-to-be-working" constraints are per major/minor Python version. You can use them as constraint
files when installing Airflow from PyPI. Note that you have to specify the correct Airflow
and Python versions in the URL.
This way, we keep a tested set of dependencies at the moment of release. This provides you with the ability
of having the exact same installation of airflow + providers + dependencies as was known to be working
at the moment of release - frozen set of dependencies for that version of Airflow. There is a separate
constraints file for each version of Python that Airflow supports.

You can create the URL to the file substituting the variables in the template below.

Expand All @@ -72,50 +104,125 @@ where:
- ``AIRFLOW_VERSION`` - Airflow version (e.g. :subst-code:`|version|`) or ``main``, ``2-0``, for latest development version
- ``PYTHON_VERSION`` Python version e.g. ``3.8``, ``3.7``

There is also a ``constraints-no-providers`` constraint file, which contains just constraints required to
install Airflow core. This allows to install and upgrade airflow separately and independently from providers.
The examples below assume that you want to use install airflow in a reproducible way with the ``celery`` extra,
but you can pick your own set of extras and providers to install.

You can create the URL to the file substituting the variables in the template below.
.. code-block:: bash
.. code-block::
pip install "apache-airflow[celery]==|version|" --constraint "https://raw.githubusercontent.com/apache/airflow/constraints-|version|/constraints-3.7.txt"
https://raw.githubusercontent.com/apache/airflow/constraints-${AIRFLOW_VERSION}/constraints-no-providers-${PYTHON_VERSION}.txt
You can also use "latest" as version when you install "latest" stable version of Airflow. The "latest"
constraints always points to the "latest" released Airflow version constraints:
.. note::

.. code-block::
The reproducible installation guarantees that this initial installation steps will always work for you -
providing that you use the right Python version and that you have appropriate Operating System dependencies
installed for the providers to be installed. Some of the providers require additional OS dependencies to
be installed such as ``build-essential`` in order to compile libraries, or for example database client
libraries in case you install a database provider, etc.. You need to figure out which system dependencies
you need when your installation fails and install them before retrying the installation.

Upgrading and installing dependencies (including providers)
===========================================================

**The reproducible installation above should not prevent you from being able to upgrade or downgrade
providers and other dependencies to other versions**

You can, for example, install new versions of providers and dependencies after the release to use the latest
version and up-to-date with latest security fixes - even if you do not want upgrade airflow core version.
Or you can downgrade some dependencies or providers if you want to keep previous versions for compatibility
reasons. Installing such dependencies should be done without constraints as a separate pip command.

When you do such an upgrade, you should make sure to also add the ``apache-airflow`` package to the list of
packages to install and pin it to the version that you have, otherwise you might end up with a
different version of Airflow than you expect because ``pip`` can upgrade/downgrade it automatically when
performing dependency resolution.


.. code-block:: bash
https://raw.githubusercontent.com/apache/airflow/constraints-latest/constraints-3.7.txt
pip install "apache-airflow[celery]==|version|" --constraint "https://raw.githubusercontent.com/apache/airflow/constraints-|version|/constraints-3.8.txt"
pip install "apache-airflow==|version|" apache-airflow-providers-google==10.1.1
You can also downgrade or upgrade other dependencies this way - even if they are not compatible with
those dependencies that are stored in the original constraints file:

.. code-block:: bash
pip install "apache-airflow[celery]==|version|" --constraint "https://raw.githubusercontent.com/apache/airflow/constraints-|version|/constraints-3.8.txt"
pip install "apache-airflow[celery]==|version|" dbt-core==0.20.0
.. warning::

Not all dependencies can be installed this way - you might have dependencies conflicting with basic
requirements of Airflow or other dependencies installed in your system. However, by skipping constraints
when you install or upgrade dependencies, you give ``pip`` a chance to resolve the conflicts for you,
while keeping dependencies within the limits that Apache Airflow, providers and other dependencies require.
The resulting combination of those dependencies and the set of dependencies that come with the
constraints might not be tested before, but it should work in most cases as we usually add
requirements, when Airflow depends on particular versions of some dependencies. In cases you cannot
install some dependencies in the same environment as Airflow - you can attempt to use other approaches.
See :ref:`best practices for handling conflicting/complex Python dependencies <best_practices/handling_conflicting_complex_python_dependencies>`


Verifying installed dependencies
================================

Fixing Constraint files at release time
'''''''''''''''''''''''''''''''''''''''
You can also always run the ``pip check`` command to test if the set of your Python packages is
consistent and not conflicting.


.. code-block:: bash
> pip check
No broken requirements found.
When you see such message and the exit code from ``pip check`` is 0, you can be sure, that there are no
conflicting dependencies in your environment.


Using your own constraints
==========================

When you decide to install your own dependencies, or want to upgrade or downgrade providers, you might want
to continue being able to keep reproducible installation of Airflow and those dependencies via a single command.
In order to do that, you can produce your own constraints file and use it to install Airflow instead of the
one provided by the community.

.. code-block:: bash
pip install "apache-airflow[celery]==|version|" --constraint "https://raw.githubusercontent.com/apache/airflow/constraints-|version|/constraints-3.8.txt"
pip install "apache-airflow==|version|" dbt-core==0.20.0
pip freeze > my-constraints.txt
Then you can use it to create reproducible installations of your environment in a single operation via
a local constraints file:

.. code-block:: bash
pip install "apache-airflow[celery]==|version|" --constraint "my-constraints.txt"
Similarly as in case of Airflow original constraints, you can also host your constraints at your own
repository or server and use it remotely from there.

Fixing Constraints at release time
''''''''''''''''''''''''''''''''''

The released "versioned" constraints are mostly ``fixed`` when we release Airflow version and we only
update them in exceptional circumstances. For example when we find out that the released constraints might prevent
Airflow from being installed consistently from the scratch. In normal circumstances, the constraint files
are not going to change if new version of Airflow dependencies are released - not even when those
versions contain critical security fixes. The process of Airflow releases is designed around upgrading
dependencies automatically where applicable but only when we release a new version of Airflow,
not for already released versions.

If you want to make sure that Airflow dependencies are upgraded to the latest released versions containing
latest security fixes, you should implement your own process to upgrade those yourself when
you detect the need for that. Airflow usually does not upper-bound versions of its dependencies via
requirements, so you should be able to upgrade them to the latest versions - usually without any problems.

Obviously - since we have no control over what gets released in new versions of the dependencies, we
cannot give any guarantees that tests and functionality of those dependencies will be compatible with
Airflow after you upgrade them - testing if Airflow still works with those is in your hands,
and in case of any problems, you should raise issue with the authors of the dependencies that are problematic.
You can also - in such cases - look at the `Airflow issues <https://github.com/apache/airflow/issues>`_
`Airflow Pull Requests <https://github.com/apache/airflow/pulls>`_ and
`Airflow Discussions <https://github.com/apache/airflow/discussions>`_, searching for similar
problems to see if there are any fixes or workarounds found in the ``main`` version of Airflow and apply them
to your deployment.

The easiest way to keep-up with the latest released dependencies is however, to upgrade to the latest released
Airflow from being installed consistently from the scratch.

In normal circumstances, the constraint files are not going to change if new version of Airflow
dependencies are released - not even when those versions contain critical security fixes.
The process of Airflow releases is designed around upgrading dependencies automatically where
applicable but only when we release a new version of Airflow, not for already released versions.

Between the releases you can upgrade dependencies on your own and you can keep your own constraints
updated as described in the previous section.

The easiest way to keep-up with the latest released dependencies is to upgrade to the latest released
Airflow version. Whenever we release a new version of Airflow, we upgrade all dependencies to the latest
applicable versions and test them together, so if you want to keep up with those tests - staying up-to-date
with latest version of Airflow is the easiest way to update those dependencies.
Expand All @@ -140,16 +247,15 @@ a one-liner (the example below installs Postgres and Google providers, as well a
pip install "apache-airflow[async,postgres,google]==${AIRFLOW_VERSION}" --constraint "${CONSTRAINT_URL}"
Note, that it will install the versions of providers that were available at the moment this version of Airflow
has been prepared. You need to follow next steps if you want to upgrade provider packages in case they were
released afterwards.
has been released. You need to run separate ``pip`` commands without constraints, if you want to upgrade
provider packages in case they were released afterwards.


Upgrading Airflow with providers
================================
Upgrading Airflow together with providers
=========================================

You can upgrade airflow together with extras (providers available at the time of the release of Airflow
being installed.

being installed. This will bring ``apache-airflow`` and all providers to the versions that were
released and tested together when the version of Airflow you are installing was released.

.. code-block:: bash
:substitutions:
Expand All @@ -159,27 +265,21 @@ being installed.
CONSTRAINT_URL="https://raw.githubusercontent.com/apache/airflow/constraints-${AIRFLOW_VERSION}/constraints-${PYTHON_VERSION}.txt"
pip install "apache-airflow[postgres,google]==${AIRFLOW_VERSION}" --constraint "${CONSTRAINT_URL}"
Installing/upgrading/downgrading providers separately from Airflow core
=======================================================================

In order to add new features, implement bug-fixes or simply maintain backwards compatibility, you might need
to install, upgrade or downgrade any of the providers you need. We release providers independently from the
core of Airflow, so often new versions of providers are released before Airflow is, also if you do not want
yet to upgrade Airflow to the latest version, you might want to install newly released providers separately.
For installing the providers you should not use any constraint files (the constraints are for installing
Airflow with providers, not to install providers separately).
You should run provider's installation as a separate command after Airflow has been installed (usually
with constraints). Constraints are only effective during the ``pip install`` command they were used with.
Managing providers separately from Airflow core
===============================================

.. code-block:: bash
In order to add new features, implement bug-fixes or simply maintain backwards compatibility, you might need
to install, upgrade or downgrade any of the providers - separately from the Airflow Core package. We release
providers independently from the core of Airflow, so often new versions of providers are released before
Airflow is, also if you do not want yet to upgrade Airflow to the latest version, you might want to
install just some (or all) newly released providers separately.

pip install "apache-airflow-providers-google==8.0.0"
As you saw above, when installing the providers separately, you should not use any constraint files.

Note, that installing, upgrading, downgrading providers separately is not guaranteed to work with all
Airflow versions or other providers. Some providers have minimum-required version of Airflow and some
versions of providers might have conflicting requirements with Airflow or other dependencies you
might have installed.
If you build your environment automatically, You should run provider's installation as a
separate command after Airflow has been installed (usually with constraints).
Constraints are only effective during the ``pip install`` command they were used with.

It is the best practice to install apache-airflow in the same version as the one that comes from the
original image. This way you can be sure that ``pip`` will not try to downgrade or upgrade apache
Expand All @@ -190,11 +290,27 @@ that conflicts with the version of apache-airflow that you are using:
pip install "apache-airflow==|version|" "apache-airflow-providers-google==8.0.0"
.. note::

Installing, upgrading, downgrading providers separately is not guaranteed to work with all
Airflow versions or other providers. Some providers have minimum-required version of Airflow and some
versions of providers might have limits on dependencies that are conflicting with limits of other
providers or other dependencies installed. For example google provider before 10.1.0 version had limit
of protobuf library ``<=3.20.0`` while for example ``google-ads`` library that is supported by google
has requirement for protobuf library ``>=4``. In such cases installing those two dependencies alongside
in a single environment will not work. In such cases you can attempt to use other approaches.
See :ref:`best practices for handling conflicting/complex Python dependencies <best_practices/handling_conflicting_complex_python_dependencies>`

Installation and upgrade of Airflow core
========================================

If you don't want to install any extra providers, initially you can use the command set below.
Managing just Airflow core without providers
============================================

If you don't want to install any providers you have, just install or upgrade Apache Airflow, you can simply
install airflow in the version you need. You can use the special ``constraints-no-providers`` constraints
file, which is smaller and limits the dependencies to the core of Airflow only, however this can lead to
conflicts if your environment already has some of the dependencies installed in different versions and
in case you have other providers installed. This command, however, gives you the latest versions of
dependencies compatible with just airflow core at the moment Airflow was released.

.. code-block:: bash
:substitutions:
Expand Down

0 comments on commit 4cb0536

Please sign in to comment.