From 4cb0536c0955ed4112e498a8472574e0e9605627 Mon Sep 17 00:00:00 2001 From: Jarek Potiuk Date: Wed, 14 Jun 2023 17:01:22 +0200 Subject: [PATCH] Update documentation for constraints installation (#31882) * 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 * Update docs/apache-airflow/installation/installing-from-pypi.rst Co-authored-by: Pankaj Koti * Update docs/apache-airflow/installation/installing-from-pypi.rst Co-authored-by: Pankaj Koti * Update docs/apache-airflow/installation/installing-from-pypi.rst Co-authored-by: Pankaj Koti * Update docs/apache-airflow/installation/installing-from-pypi.rst Co-authored-by: Pankaj Koti * Update docs/apache-airflow/installation/installing-from-pypi.rst Co-authored-by: Pankaj Koti * 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 (cherry picked from commit f8f0cbc75e9e467c2d05c38e64324e2d4ec85176) --- .../installation/installing-from-pypi.rst | 254 +++++++++++++----- 1 file changed, 185 insertions(+), 69 deletions(-) diff --git a/docs/apache-airflow/installation/installing-from-pypi.rst b/docs/apache-airflow/installation/installing-from-pypi.rst index 97cf3ba41c6b7..aff7b7ebc846d 100644 --- a/docs/apache-airflow/installation/installing-from-pypi.rst +++ b/docs/apache-airflow/installation/installing-from-pypi.rst @@ -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. @@ -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 ` + + +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 `_ -`Airflow Pull Requests `_ and -`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. @@ -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: @@ -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 @@ -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 ` -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: