The missing guide for setting up a great local development workflow for your Python projects. This is an way of developing with Python locally. You’ve probably discovered that it’s a pain in the ass to manage different projects with dependencies targeting different Python versions on your local machine. opinionated To complicate things, there are multiple ways of installing Python too: Preinstallation by the OS 😔 Using a package manager like or 😕 brew apt Using the binaries from 😫 www.python.org Using —easy way to install and manage Python installations 😎 pyenv This guide uses pyenv to manage Python installations, and Pipenv to manage project dependencies (instead of raw pip). Installing pyenv Let’s install via : brew $ brew install pyenv If you’re not on Mac, please see pyenv’s installation instructions . Add the following to your , or (depending on your shell) to automatically initialize pyenv when your terminal loads: ~/.bash_profile ~/.bashrc eval "$(pyenv init -)" How does pyenv work? See all available Python versions: $ pyenv install --list Let’s install Python 3.6.6 $ pyenv install 3.6.6 Installed Python-3.6.6 to /Users/dvf/.pyenv/versions/3.6.6 pyenv won’t change your global interpreter unless you tell it to: $ python --version Python 2.7.14 $ pyenv global 3.6.6 Python 3.6.6 pyenv allows you to install different versions of Python to a directory. Let’s create a project targeting Python 3.7.0: local $ pyenv install 3.7.0 Installed Python-3.7.0 to /Users/dvf/.pyenv/versions/3.7.0 $ mkdir my_project && cd my_project$ python --version Python 3.6.6 $ pyenv local 3.7.0$ python --version Python 3.7.0 Now whenever you find yourself in you’ll automatically use the Python 3.7.0 interpreter. my_project If not, stop here and take some time to play around with pyenv—it works by installing all Python interpreters in and dynamically adjusting your depending on your current directory. 🤚Did that make sense? ~/.pyenv $PATH What is Pipenv and how does it work? is the officially recommended way of managing project dependencies. Instead of having a file in your project, and managing virtualenvs, you'll now have a in your project that does all this stuff automatically. Pipenv requirements.txt Pipfile Start off by installing it via , it’s a rapidly evolving project so make sure you have the latest version (2018.10.13 at the time of writing): pip $ pip install -U pipenv Using Pipenv for the first time Let’s set up Pipenv in your project: $ cd my_project$ pipenv install Creating a virtualenv for this project… Pipfile: /Users/dvf/my_project/Pipfile Using /Users/dvf/.pyenv/versions/3.7.0/bin/python3.7 (3.7.0) to create virtualenv… You’ll find two new files in your project: and . Pipfile Pipfile.lock If you’re installing in a pre-existing project, Pipenv will convert your old into a . How cool is that? requirements.txt Pipfile This is what your should look like for a fresh project: Pipfile [[source]]url = "https://pypi.org/simple"verify_ssl = truename = "pypi" [packages] [dev-packages] [requires]python_version = "3.7" , Pipenv takes care of virtual environments for us. So, installing new dependencies is simple: Notice that we didn’t activate any virtual environments here $ pipenv install django Installing django... Installing collected packages: pytz, djangoSuccessfully installed django-2.1.2 pytz-2018.5 Adding django to Pipfile's [packages]…Pipfile.lock (4f9dd2) out of date, updating to (a65489)…Locking [dev-packages] dependencies…Locking [packages] dependencies…Updated Pipfile.lock (4f9dd2)! Installing dependencies from Pipfile.lock (4f9dd2)… 🐍 ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 2/2 — 00:00:01 To activate this project's virtualenv, run pipenv shell.Alternatively, run a command inside the virtualenv with pipenv run. If you inspect your you’ll notice it now contains as a dependency. Pipfile django = "*" If we wanted to install dev dependencies for use during development, for example , you’d add to the install step: YAPF --dev $ pipenv install --dev yapf What is **Pipfile.lock** ? is super important because it does two things: Pipfile.lock Provides good security by keeping a hash of each package installed. Pins the versions of all dependencies and sub-dependencies, giving you replicable environments. Let’s see what it currently looks like: {"_meta": {"hash": {"sha256": "627ef89...64f9dd2"},"pipfile-spec": 6,"requires": {"python_version": "3.7"},"sources": [{"name": "pypi","url": " ","verify_ssl": true}]},"default": {"django": {"hashes": ["sha256:acdcc1...ab5bb3","sha256:efbcad...d16b45"],"index": "pypi","version": "==2.1.2"},"pytz": {"hashes": ["sha256:a061aa...669053","sha256:ffb9ef...2bf277"],"version": "==2018.5"}},"develop": {}} https://pypi.org/simple Notice that the versions of each dependency are pinned. Without a good reason, you would always want this file committed to your source control. very Custom Indexes Until Pipenv it was difficult to use Python repositories, for example if you’d like to host private Python libraries within your organization. Now all you need to do is define them as an additional sources in the : private Pipfile [[source]]url = "https://pypi.org/simple"verify_ssl = truename = "pypi"[[source]]url = "https://www.example.com"verify_ssl = truename = "some-repo-name"[packages]django = "*"my-private-app = {version="*", index="some-repo-name"}[dev-packages][requires]python_version = "3.7" Notice that we told to use the private repo. If omitted, Pipenv will cycle through indexes until it finds the package. my-private-app 💡Pipenv will also consume any environment variables in values , which is useful if you have sensitive credentials you don’t want sitting in source control (this was my contribution _</humblebrag>_ ) Deploying When deploying it’s important that your deploy fails if there’s a mismatch between installed dependencies and the . So you should append to your install step which does just that: Pipfile.lock --deploy $ pipenv install --deploy You could also check which dependencies are mismatched: $ pipenv check And see which sub-dependencies are installed by packages: $ pipenv graph --reverse pip==18.1 pytz==2018.5 Django 40.4.3** 2.1.2 [requires: pytz]**setuptools wheel==0.32.2 yapf==0.24.0 Once-off commands, scripts and activating venvs If you’re actively developing a project, it’s helpful to activate the virtual environment: $ pipenv shell Launching subshell in virtual environment… Or, if you’d like to execute a command inside the venv: $ pipenv run python manage.py runserver You can also add scripts to similar to : Pipfile npm package.json [[source]]url = " "verify_ssl = truename = "pypi" https://pypi.org/simple [packages]django = "*" [dev-packages]yapf = "*" [scripts]server = "python manage.py runserver" [requires]python_version = "3.7" Now you can execute the script: $ pipenv run server We’ve just touched the tip of the iceberg. If you’ve like to learn more about Pipenv, I encourage you to read the . great documentation I hope this was helpful to you. And I’d love to hear any thoughts or suggestions you have in the comments!
Share Your Thoughts