def install_requirements_to()

in syndicate/core/build/runtime/python.py [0:0]


def install_requirements_to(requirements_txt: Union[str, Path],
                            to: Union[str, Path],
                            config: Optional[dict] = None,
                            errors_allowed: bool = False):
    """
    1. If there is NO "platform" parameter in lambda_config.json, then the
    dependency installation will be executed by the default command:
    "pip install -r requirements.txt".

    2. If there is NO "platform" parameter in lambda_config.json and flag
    --errors_allowed is True, dependency installation will be tried by
    executing the default command: "pip install -r requirements.txt" in case
    of failures, installation of dependencies will be performed separately
    for each dependency using the default command:
    "pip install <package1>
    pip install <packageN>".

    3. If there is "platform" parameter in lambda_config.json and flag
    --errors_allowed is False, then the dependency installation will be
    executed by the default command using additional parameters:
    "pip install -r requirements.txt --platform manylinux2014_x86_64
    --only-binary=:all: --implementation=cp --python-version 3.8".

    4. If there is "platform" parameter in lambda_config.json and flag
    --errors_allowed is True, dependency installation will be tried by the
    default command using additional parameters:
    "pip install -r requirements.txt --platform manylinux2014_x86_64
    --only-binary=:all: --implementation=cp --python-version 3.8",
    in case of failures, installation of dependencies will be performed
    separately for each dependency using the default command using additional
    parameters. Dependencies that do not have a specified platform will be
    installed with the --platform=any:
    "pip install <package1> --platform manylinux2014_x86_64
    --only-binary=:all: --implementation=cp --python-version 3.8
    pip install <packageN> --platform manylinux2014_x86_64
    --only-binary=:all: --implementation=cp --python-version 3.8
    pip install <packageN+1>".
    """

    exit_code = None
    config = config or {}
    _LOG.info('Going to install 3-rd party dependencies')
    supported_platforms = update_platforms(set(config.get('platforms') or []))
    python_version = _get_python_version(lambda_config=config)
    if supported_platforms:
        command = build_pip_install_command(  # default installation
            requirement=requirements_txt,
            to=to,
            platforms=supported_platforms,
            python=python_version,
            only_binary=':all:',
            implementation='cp'
        )
        result = subprocess.run(command, capture_output=True, text=True)
        _LOG.info(f'\n{result.stdout}\n{result.stderr}')
        if result.returncode != 0 and errors_allowed:
            # tries to install packages compatible with specific platforms
            # independently
            _LOG.info(
                f'Going to install 3-rd party dependencies for platforms: '
                f'{",".join(supported_platforms)}')
            failed_requirements = install_requirements_independently(
                requirements=requirements_txt,
                to=to,
                supported_platforms=supported_platforms,
                python_version=python_version
            )
            failed_requirements = install_requirements_independently(
                requirements=failed_requirements,
                to=to
            )

            _LOG.info(f'\n{result.stdout}\n{result.stderr}')
            if failed_requirements:
                message = (f'An error occurred while installing '
                           f'requirements: "{failed_requirements}" for '
                           f'package "{to}"')
                _LOG.error(message)
                raise RuntimeError(message)
        elif result.returncode != 0:
            exit_code = result.returncode
    else:
        _LOG.info('Installing all the requirements with defaults')
        command = build_pip_install_command(
            requirement=requirements_txt,
            to=to
        )
        result = subprocess.run(command, capture_output=True, text=True)
        exit_code = result.returncode

        if result.returncode != 0 and errors_allowed:
            # tries to install packages independently
            _LOG.info(
                'Installing the requirements with defaults independently')
            failed_requirements = install_requirements_independently(
                requirements=requirements_txt,
                to=to
            )

            _LOG.info(f'\n{result.stdout}\n{result.stderr}')
            if failed_requirements:
                message = (f'An error occurred while installing '
                           f'requirements: "{failed_requirements}" for '
                           f'package "{to}"')
                _LOG.error(message)
                raise RuntimeError(message)

    if exit_code:
        message = (f'An error: \n"{result.stdout}\n{result.stderr}"\noccurred '
                   f'while installing requirements: "{str(requirements_txt)}" '
                   f'for package "{to}"\nUse --errors_allowed flag to ignore '
                   f'failures in dependencies installation.')
        _LOG.error(message)
        raise RuntimeError(message)
    if exit_code == 0:
        _LOG.info(f'\n{result.stdout}\n{result.stderr}')
    _LOG.info('3-rd party dependencies were installed successfully')