brew install pyenv
pip install pipenv
pipenv --python 3.7
(pyenv install --list
)pipenv shell
pipenv install tornado==5.0.2
pipenv install --dev mypy tox flake8
pipenv install -r requirements.txt
(generate Pipfile from requirements.txt)pipenv lock --requirements
(generate a requirements.txt equivalent to a Pipfile)
https://github.com/pypa/pipenv
First, make sure you're using your system install of Python (likely 2.7.x) and you have no other python environments installed, otherwise that may cause you confusion if things don't work as you expect (basically, have a spring clean of your previous/old python setup).
Next make sure you have pyenv
installed (e.g. brew install pyenv
) as Pipenv uses that for installing python versions.
Note: it's unclear if Pipenv will handle installing pyenv for you, so maybe try the following steps without installing pyenv and see if installing a new python version (as described below) works or not.
pip install pipenv
Note: also, if you try to install a new Python version, I've noticed it errors saying
python-build
definitions are out of date and need to be updated to install the new version. Thepython-build
is used bypyenv
so again, it's unclear ifpython-build
is installed by Pipenv or if it has to be manually installed along withpyenv
🤔
Here's an example Dockerfile
to try things out:
FROM python:3.6.5
# Jump into directory where our Pipfile will be found
WORKDIR /app
# Install pipenv for managing dependencies instead of pip
RUN pip install -U pipenv==10.*
# This pip.conf configures pip to use our internal pypi mirror when installing
# python packages. It's not in this service's directory, but is put in place
# the .rig/hooks/prebuild_setup_internal_packages global prebuild hook before
# the image is built.
COPY pip.conf /etc/pip.conf
# Copy over both Pipfile and Pipfile.lock
COPY ./Pipfile* /app/
# Install all dependencies to the system version (3.6.5)
RUN pipenv install --system --deploy
COPY . /app/
CMD ["/app/service.py"]
For me this installed pipenv-2018.5.18
.
Here are the basic commands available with pipenv
:
$ pipenv
Usage: pipenv [OPTIONS] COMMAND [ARGS]...
Options:
--where Output project home information.
--venv Output virtualenv information.
--py Output Python interpreter information.
--envs Output Environment Variable options.
--rm Remove the virtualenv.
--bare Minimal output.
--completion Output completion (to be eval'd).
--man Display manpage.
--three / --two Use Python 3/2 when creating virtualenv.
--python TEXT Specify which version of Python virtualenv should use.
--site-packages Enable site-packages for the virtualenv.
--version Show the version and exit.
-h, --help Show this message and exit.
Usage Examples:
Create a new project using Python 3.6, specifically:
$ pipenv --python 3.6
Install all dependencies for a project (including dev):
$ pipenv install --dev
Create a lockfile containing pre-releases:
$ pipenv lock --pre
Show a graph of your installed dependencies:
$ pipenv graph
Check your installed dependencies for security vulnerabilities:
$ pipenv check
Install a local setup.py into your virtual environment/Pipfile:
$ pipenv install -e .
Use a lower-level pip command:
$ pipenv run pip freeze
Commands:
check Checks for security vulnerabilities and against PEP 508 markers
provided in Pipfile.
clean Uninstalls all packages not specified in Pipfile.lock.
graph Displays currently–installed dependency graph information.
install Installs provided packages and adds them to Pipfile, or (if none
is given), installs all packages.
lock Generates Pipfile.lock.
open View a given module in your editor.
run Spawns a command installed into the virtualenv.
shell Spawns a shell within the virtualenv.
sync Installs all packages specified in Pipfile.lock.
uninstall Un-installs a provided package and removes it from Pipfile.
update Runs lock, then sync.
Let's create a new project using Python 3.6:
$ pipenv --python 3.6
Creating a virtualenv for this project…
Using /Users/markmcdonnell/.pyenv/versions/3.6.3/bin/python3.6m (3.6.3) to create virtualenv…
⠋Running virtualenv with interpreter /Users/markmcdonnell/.pyenv/versions/3.6.3/bin/python3.6m
Using base prefix '/Users/markmcdonnell/.pyenv/versions/3.6.3'
New python executable in /Users/markmcdonnell/.local/share/virtualenvs/testing_pipenv-jvIwu3TP/bin/python3.6m
Also creating executable in /Users/markmcdonnell/.local/share/virtualenvs/testing_pipenv-jvIwu3TP/bin/python
Installing setuptools, pip, wheel...done.
Virtualenv location: /Users/markmcdonnell/.local/share/virtualenvs/testing_pipenv-jvIwu3TP
Creating a Pipfile for this project…
This will create a Pipfile
:
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[dev-packages]
[packages]
[requires]
python_version = "3.6"
But the current terminal/shell will be using the system Python still:
$ python --version
Python 2.7.10
In order to use the installed Python environment, you need to spin up a new shell:
$ pipenv shell
Spawning environment shell (/usr/local/bin/bash). Use 'exit' to leave.
. /Users/markmcdonnell/.local/share/virtualenvs/testing_pipenv-jvIwu3TP/bin/activate
$ python --version
Python 3.6.3
Note: when switching between git branches you might find odd things happen. I've found the best thing to do is to first check with
python --version
to see if you're using the system python or not and if you are using Pipenv still, to thenexit
so you leave the virtual environment shell that's running. Then change your git branch and move into whatever directory you need to and re-runpipenv shell
.
Let's install two dependencies (we'll see the Pipfile
is updated and a Pipfile.lock
is generated):
$ pipenv install boto3
Installing boto3…
Collecting boto3
Downloading https://files.pythonhosted.org/packages/b8/29/f35b0a055014296bf4188043e2cc1fd4ca041a085991765598842232c2f5/boto3-1.7.26-py2.py3-none-any.whl (128kB)
Collecting jmespath<1.0.0,>=0.7.1 (from boto3)
Using cached https://files.pythonhosted.org/packages/b7/31/05c8d001f7f87f0f07289a5fc0fc3832e9a57f2dbd4d3b0fee70e0d51365/jmespath-0.9.3-py2.py3-none-any.whl
Collecting s3transfer<0.2.0,>=0.1.10 (from boto3)
Using cached https://files.pythonhosted.org/packages/d7/14/2a0004d487464d120c9fb85313a75cd3d71a7506955be458eebfe19a6b1d/s3transfer-0.1.13-py2.py3-none-any.whl
Collecting botocore<1.11.0,>=1.10.26 (from boto3)
Downloading https://files.pythonhosted.org/packages/87/c5/7ed94b700d30534f346bb55408ca8501325840bcdc371628cff10d7ba68d/botocore-1.10.26-py2.py3-none-any.whl (4.2MB)
Collecting docutils>=0.10 (from botocore<1.11.0,>=1.10.26->boto3)
Downloading https://files.pythonhosted.org/packages/36/fa/08e9e6e0e3cbd1d362c3bbee8d01d0aedb2155c4ac112b19ef3cae8eed8d/docutils-0.14-py3-none-any.whl (543kB)
Collecting python-dateutil<3.0.0,>=2.1; python_version >= "2.7" (from botocore<1.11.0,>=1.10.26->boto3)
Using cached https://files.pythonhosted.org/packages/cf/f5/af2b09c957ace60dcfac112b669c45c8c97e32f94aa8b56da4c6d1682825/python_dateutil-2.7.3-py2.py3-none-any.whl
Collecting six>=1.5 (from python-dateutil<3.0.0,>=2.1; python_version >= "2.7"->botocore<1.11.0,>=1.10.26->boto3)
Downloading https://files.pythonhosted.org/packages/67/4b/141a581104b1f6397bfa78ac9d43d8ad29a7ca43ea90a2d863fe3056e86a/six-1.11.0-py2.py3-none-any.whl
Installing collected packages: jmespath, docutils, six, python-dateutil, botocore, s3transfer, boto3
Successfully installed boto3-1.7.26 botocore-1.10.26 docutils-0.14 jmespath-0.9.3 python-dateutil-2.7.3 s3transfer-0.1.13 six-1.11.0
Adding boto3 to Pipfile's [packages]…
Pipfile.lock not found, creating…
Locking [dev-packages] dependencies…
Locking [packages] dependencies…
Updated Pipfile.lock (00df60)!
Installing dependencies from Pipfile.lock (00df60)…
🐍 ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 7/7 — 00:00:01
$ pipenv install ipython
...same sort of stuff..
$ pipenv install pyre-check --dev
...same sort of stuff..
Here's a look at the current Pipfile
:
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[dev-packages]
pyre-check = "*"
[packages]
"boto3" = "*"
ipython = "*"
[requires]
python_version = "3.6"
We can now utilise these dependencies:
$ which ipython
/Users/markmcdonnell/.local/share/virtualenvs/testing_pipenv-jvIwu3TP/bin/ipython
$ ipython
Python 3.6.3 (default, Oct 13 2017, 11:47:13)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.4.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import boto3
In [2]: type(boto3.client('cognito-idp'))
Out[2]: botocore.client.CognitoIdentityProvider
There are other ways to install dependencies:
- Explicit versions:
pipenv install flask==0.12.1
- Git:
pipenv install -e git+https://github.com/requests/requests.git#egg=requests
- AWS Lambda zip generation:
pipenv run pip install -r <(pipenv lock -r) --target dist/
You can also graph out all your dependencies:
$ pipenv graph
boto3==1.7.26
- botocore [required: >=1.10.26,<1.11.0, installed: 1.10.26]
- docutils [required: >=0.10, installed: 0.14]
- jmespath [required: <1.0.0,>=0.7.1, installed: 0.9.3]
- python-dateutil [required: >=2.1,<3.0.0, installed: 2.7.3]
- six [required: >=1.5, installed: 1.11.0]
- jmespath [required: <1.0.0,>=0.7.1, installed: 0.9.3]
- s3transfer [required: <0.2.0,>=0.1.10, installed: 0.1.13]
- botocore [required: >=1.3.0,<2.0.0, installed: 1.10.26]
- docutils [required: >=0.10, installed: 0.14]
- jmespath [required: <1.0.0,>=0.7.1, installed: 0.9.3]
- python-dateutil [required: >=2.1,<3.0.0, installed: 2.7.3]
- six [required: >=1.5, installed: 1.11.0]
ipython==6.4.0
- appnope [required: Any, installed: 0.1.0]
- backcall [required: Any, installed: 0.1.0]
- decorator [required: Any, installed: 4.3.0]
- jedi [required: >=0.10, installed: 0.12.0]
- parso [required: >=0.2.0, installed: 0.2.1]
- pexpect [required: Any, installed: 4.5.0]
- ptyprocess [required: >=0.5, installed: 0.5.2]
- pickleshare [required: Any, installed: 0.7.4]
- prompt-toolkit [required: >=1.0.15,<2.0.0, installed: 1.0.15]
- six [required: >=1.9.0, installed: 1.11.0]
- wcwidth [required: Any, installed: 0.1.7]
- pygments [required: Any, installed: 2.2.0]
- setuptools [required: >=18.5, installed: 39.2.0]
- simplegeneric [required: >0.8, installed: 0.8.1]
- traitlets [required: >=4.2, installed: 4.3.2]
- decorator [required: Any, installed: 4.3.0]
- ipython-genutils [required: Any, installed: 0.2.0]
- six [required: Any, installed: 1.11.0]
pyre-check==0.0.6
typed-ast==1.1.0
You can reverse the graph direction using the
--reverse
flag.
You can verify the security of your dependencies:
$ pipenv check
Checking PEP 508 requirements…
Passed!
Checking installed package safety…
All good!
You can also look at the code for any of your dependencies, and their code directory will be opened in whichever editor is assigned to the $EDITOR
environment variable in your shell (for me this is vim
):
$ pipenv open boto3
Opening '/Users/markmcdonnell/.local/share/virtualenvs/testing_pipenv-jvIwu3TP/lib/python3.6/site-packages/boto3' in your EDITOR.
Here's a look at our final Pipfile.lock
:
{
"_meta": {
"hash": {
"sha256": "e79d3c5ef5705053b19f7c653dc0adb3e99d75726138633ae95a5b3709f2e51c"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.6"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {
"appnope": {
"hashes": [
"sha256:5b26757dc6f79a3b7dc9fab95359328d5747fcb2409d331ea66d0272b90ab2a0",
"sha256:8b995ffe925347a2138d7ac0fe77155e4311a0ea6d6da4f5128fe4b3cbe5ed71"
],
"markers": "sys_platform == 'darwin'",
"version": "==0.1.0"
},
"backcall": {
"hashes": [
"sha256:38ecd85be2c1e78f77fd91700c76e14667dc21e2713b63876c0eb901196e01e4",
"sha256:bbbf4b1e5cd2bdb08f915895b51081c041bac22394fdfcfdfbe9f14b77c08bf2"
],
"version": "==0.1.0"
},
"boto3": {
"hashes": [
"sha256:6dd9a6fe523c3e4d4fc28fe7030453ee5b4e75e778144cf22008c79dfc031bd3",
"sha256:fccad296209cfbee668292d51bd3b258eb85d4bce1bf1a5dcb2e24942a00d48a"
],
"index": "pypi",
"version": "==1.7.26"
},
"botocore": {
"hashes": [
"sha256:c63c77e41cd514d80da06eb626f5e9f50c94c44b0206957aca23a20f889abb05",
"sha256:ca23fb013a18584a3a7043c6cc0bf02250f2665937e73290f65f1f48ee9b4f78"
],
"version": "==1.10.26"
},
"decorator": {
"hashes": [
"sha256:2c51dff8ef3c447388fe5e4453d24a2bf128d3a4c32af3fabef1f01c6851ab82",
"sha256:c39efa13fbdeb4506c476c9b3babf6a718da943dab7811c206005a4a956c080c"
],
"version": "==4.3.0"
},
"docutils": {
"hashes": [
"sha256:02aec4bd92ab067f6ff27a38a38a41173bf01bed8f89157768c1573f53e474a6",
"sha256:51e64ef2ebfb29cae1faa133b3710143496eca21c530f3f71424d77687764274",
"sha256:7a4bd47eaf6596e1295ecb11361139febe29b084a87bf005bf899f9a42edc3c6"
],
"version": "==0.14"
},
"ipython": {
"hashes": [
"sha256:a0c96853549b246991046f32d19db7140f5b1a644cc31f0dc1edc86713b7676f",
"sha256:eca537aa61592aca2fef4adea12af8e42f5c335004dfa80c78caf80e8b525e5c"
],
"index": "pypi",
"version": "==6.4.0"
},
"ipython-genutils": {
"hashes": [
"sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8",
"sha256:eb2e116e75ecef9d4d228fdc66af54269afa26ab4463042e33785b887c628ba8"
],
"version": "==0.2.0"
},
"jedi": {
"hashes": [
"sha256:1972f694c6bc66a2fac8718299e2ab73011d653a6d8059790c3476d2353b99ad",
"sha256:5861f6dc0c16e024cbb0044999f9cf8013b292c05f287df06d3d991a87a4eb89"
],
"version": "==0.12.0"
},
"jmespath": {
"hashes": [
"sha256:6a81d4c9aa62caf061cb517b4d9ad1dd300374cd4706997aff9cd6aedd61fc64",
"sha256:f11b4461f425740a1d908e9a3f7365c3d2e569f6ca68a2ff8bc5bcd9676edd63"
],
"version": "==0.9.3"
},
"parso": {
"hashes": [
"sha256:cdef26e8adc10d589f3ec4eb444bd0a29f3f1eb6d72a4292ab8afcb9d68976a6",
"sha256:f0604a40b96e062b0fd99cf134cc2d5cdf66939d0902f8267d938b0d5b26707f"
],
"version": "==0.2.1"
},
"pexpect": {
"hashes": [
"sha256:9783f4644a3ef8528a6f20374eeb434431a650c797ca6d8df0d81e30fffdfa24",
"sha256:9f8eb3277716a01faafaba553d629d3d60a1a624c7cf45daa600d2148c30020c"
],
"markers": "sys_platform != 'win32'",
"version": "==4.5.0"
},
"pickleshare": {
"hashes": [
"sha256:84a9257227dfdd6fe1b4be1319096c20eb85ff1e82c7932f36efccfe1b09737b",
"sha256:c9a2541f25aeabc070f12f452e1f2a8eae2abd51e1cd19e8430402bdf4c1d8b5"
],
"version": "==0.7.4"
},
"prompt-toolkit": {
"hashes": [
"sha256:1df952620eccb399c53ebb359cc7d9a8d3a9538cb34c5a1344bdbeb29fbcc381",
"sha256:3f473ae040ddaa52b52f97f6b4a493cfa9f5920c255a12dc56a7d34397a398a4",
"sha256:858588f1983ca497f1cf4ffde01d978a3ea02b01c8a26a8bbc5cd2e66d816917"
],
"version": "==1.0.15"
},
"ptyprocess": {
"hashes": [
"sha256:e64193f0047ad603b71f202332ab5527c5e52aa7c8b609704fc28c0dc20c4365",
"sha256:e8c43b5eee76b2083a9badde89fd1bbce6c8942d1045146e100b7b5e014f4f1a"
],
"version": "==0.5.2"
},
"pygments": {
"hashes": [
"sha256:78f3f434bcc5d6ee09020f92ba487f95ba50f1e3ef83ae96b9d5ffa1bab25c5d",
"sha256:dbae1046def0efb574852fab9e90209b23f556367b5a320c0bcb871c77c3e8cc"
],
"version": "==2.2.0"
},
"python-dateutil": {
"hashes": [
"sha256:1adb80e7a782c12e52ef9a8182bebeb73f1d7e24e374397af06fb4956c8dc5c0",
"sha256:e27001de32f627c22380a688bcc43ce83504a7bc5da472209b4c70f02829f0b8"
],
"markers": "python_version >= '2.7'",
"version": "==2.7.3"
},
"s3transfer": {
"hashes": [
"sha256:90dc18e028989c609146e241ea153250be451e05ecc0c2832565231dacdf59c1",
"sha256:c7a9ec356982d5e9ab2d4b46391a7d6a950e2b04c472419f5fdec70cc0ada72f"
],
"version": "==0.1.13"
},
"simplegeneric": {
"hashes": [
"sha256:dc972e06094b9af5b855b3df4a646395e43d1c9d0d39ed345b7393560d0b9173"
],
"version": "==0.8.1"
},
"six": {
"hashes": [
"sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9",
"sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb"
],
"version": "==1.11.0"
},
"traitlets": {
"hashes": [
"sha256:9c4bd2d267b7153df9152698efb1050a5d84982d3384a37b2c1f7723ba3e7835",
"sha256:c6cb5e6f57c5a9bdaa40fa71ce7b4af30298fbab9ece9815b5d995ab6217c7d9"
],
"version": "==4.3.2"
},
"wcwidth": {
"hashes": [
"sha256:3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e",
"sha256:f4ebe71925af7b40a864553f761ed559b43544f8f71746c2d756c7fe788ade7c"
],
"version": "==0.1.7"
}
},
"develop": {
"pyre-check": {
"hashes": [
"sha256:2d631e00c15761bdeef0e3f70e3b54f8cfa2765018d42a841cbfe7373574db6d",
"sha256:a05d569441a1eadc5acbb8574710d69171898a2c02fa196e1d162faf77dc4f02"
],
"index": "pypi",
"version": "==0.0.6"
}
}
}