@operation
def packages(
    state, host,
    packages=None, present=True, latest=False,
    requirements=None, virtualenv=None
):

    commands = []

    if requirements is not None:
        commands.append('pip install -r {0}'.format(requirements))

    current_packages = (
        host.fact.pip_virtualenv_packages(virtualenv)
        if virtualenv else host.fact.pip_packages
    )

    commands.extend(ensure_packages(
        packages, current_packages, present,
        install_command='pip install',
        uninstall_command='pip uninstall',
        version_join='==',
        upgrade_command='pip upgrade',
        latest=latest,
    ))

    # Wrap commands inside virtualenv when present
    if virtualenv:
        virtualenv = virtualenv.rstrip('/')
        commands = [
            '{0}/bin/{1}'.format(virtualenv, command)
            for command in commands
        ]

    return commands
Manage pip packages.
dataset/ETHPy150Open Fizzadar/pyinfra/pyinfra/modules/pip.py/packages