def packages(
    state, host,
    packages=None, present=True, latest=False,
    requirements=None, pip='pip', virtualenv=None, virtualenv_kwargs=None,
):
    '''
    Install/remove/update pip packages.

    + packages: list of packages to ensure
    + present: whether the packages should be installed
    + latest: whether to upgrade packages without a specified version
    + requirements: location of requirements file to install
    + pip: name or path of the pip directory to use
    + virtualenv: root directory of virtualenv to work in
    + virtualenv_kwargs: dictionary of arguments to pass to ``pip.virtualenv``

    Virtualenv:
        This will be created if it does not exist already. ``virtualenv_kwargs``
        will be passed to ``pip.virtualenv`` which can be used to control how
        the env is created.

    Versions:
        Package versions can be pinned like pip: ``<pkg>==<version>``.
    '''

    virtualenv_kwargs = virtualenv_kwargs or {}

    # Ensure any virutalenv
    if virtualenv:
        yield _virtualenv(state, host, virtualenv, **virtualenv_kwargs)

        # And update pip path
        virtualenv = virtualenv.rstrip('/')
        pip = '{0}/bin/{1}'.format(virtualenv, pip)

    # Install requirements
    if requirements is not None:
        yield '{0} install -r {1}'.format(pip, requirements)

    # Handle passed in packages
    if packages:
        current_packages = host.fact.pip_packages(pip)

        yield ensure_packages(
            packages, current_packages, present,
            install_command='{0} install'.format(pip),
            uninstall_command='{0} uninstall'.format(pip),
            upgrade_command='{0} install --upgrade'.format(pip),
            version_join='==',
            latest=latest,
        )
Install/remove/update pip packages.

    + packages: list of packages to ensure
    + present: whether the packages should be installed
    + latest: whether to upgrade packages without a specified version
    + requirements: location of requirements file to install
    + pip: name or path of the pip directory to use
    + virtualenv: root directory of virtualenv to work in
    + virtualenv_kwargs: dictionary of arguments to pass to ``pip.virtualenv``

    Virtualenv:
        This will be created if it does not exist already. ``virtualenv_kwargs``
        will be passed to ``pip.virtualenv`` which can be used to control how
        the env is created.

    Versions:
        Package versions can be pinned like pip: ``<pkg>==<version>``.