4
# Copyright 2014-2015 Canonical Limited.
6
# Licensed under the Apache License, Version 2.0 (the "License");
7
# you may not use this file except in compliance with the License.
8
# You may obtain a copy of the License at
10
# http://www.apache.org/licenses/LICENSE-2.0
12
# Unless required by applicable law or agreed to in writing, software
13
# distributed under the License is distributed on an "AS IS" BASIS,
14
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
# See the License for the specific language governing permissions and
16
# limitations under the License.
23
from charmhelpers.fetch import apt_install, apt_update
24
from charmhelpers.core.hookenv import charm_dir, log
26
__author__ = "Jorge Niedbalski <jorge.niedbalski@canonical.com>"
29
def pip_execute(*args, **kwargs):
30
"""Overriden pip_execute() to stop sys.path being changed.
32
The act of importing main from the pip module seems to cause add wheels
33
from the /usr/share/python-wheels which are installed by various tools.
34
This function ensures that sys.path remains the same after the call is
40
from pip import main as _pip_execute
44
apt_install('python-pip')
46
apt_install('python3-pip')
47
from pip import main as _pip_execute
48
_pip_execute(*args, **kwargs)
53
def parse_options(given, available):
54
"""Given a set of options, check if available"""
55
for key, value in sorted(given.items()):
59
yield "--{0}={1}".format(key, value)
62
def pip_install_requirements(requirements, constraints=None, **options):
63
"""Install a requirements file.
65
:param constraints: Path to pip constraints file.
66
http://pip.readthedocs.org/en/stable/user_guide/#constraints-files
70
available_options = ('proxy', 'src', 'log', )
71
for option in parse_options(options, available_options):
72
command.append(option)
74
command.append("-r {0}".format(requirements))
76
command.append("-c {0}".format(constraints))
77
log("Installing from file: {} with constraints {} "
78
"and options: {}".format(requirements, constraints, command))
80
log("Installing from file: {} with options: {}".format(requirements,
85
def pip_install(package, fatal=False, upgrade=False, venv=None,
86
constraints=None, **options):
87
"""Install a python package"""
89
venv_python = os.path.join(venv, 'bin/pip')
90
command = [venv_python, "install"]
94
available_options = ('proxy', 'src', 'log', 'index-url', )
95
for option in parse_options(options, available_options):
96
command.append(option)
99
command.append('--upgrade')
102
command.extend(['-c', constraints])
104
if isinstance(package, list):
105
command.extend(package)
107
command.append(package)
109
log("Installing {} package with options: {}".format(package,
112
subprocess.check_call(command)
117
def pip_uninstall(package, **options):
118
"""Uninstall a python package"""
119
command = ["uninstall", "-q", "-y"]
121
available_options = ('proxy', 'log', )
122
for option in parse_options(options, available_options):
123
command.append(option)
125
if isinstance(package, list):
126
command.extend(package)
128
command.append(package)
130
log("Uninstalling {} package with options: {}".format(package,
136
"""Returns the list of current python installed packages
138
return pip_execute(["list"])
141
def pip_create_virtualenv(path=None):
142
"""Create an isolated Python environment."""
144
apt_install('python-virtualenv')
146
apt_install('python3-virtualenv')
151
venv_path = os.path.join(charm_dir(), 'venv')
153
if not os.path.exists(venv_path):
154
subprocess.check_call(['virtualenv', venv_path])