|
| 1 | +.. slideconf:: |
| 2 | + :autoslides: False |
| 3 | + |
| 4 | +*********************** |
| 5 | +An Introduction To Venv |
| 6 | +*********************** |
| 7 | + |
| 8 | +.. slide:: An Introduction To Venv |
| 9 | + :level: 1 |
| 10 | + |
| 11 | + This document contains no slides. |
| 12 | + |
| 13 | +In this tutorial you'll learn a bit about the `pyvenv`_ command and the |
| 14 | +``venv`` module that powers it. You'll learn how to create self-contained |
| 15 | +Python environments in order to practice safe development and manage package |
| 16 | +dependency conflicts. |
| 17 | + |
| 18 | +Working with Virtual Environments |
| 19 | +================================= |
| 20 | + |
| 21 | +.. rst-class:: large |
| 22 | + |
| 23 | +| For every package |
| 24 | +| installed in the |
| 25 | +| system Python, the |
| 26 | +| gods kill a kitten |
| 27 | +
|
| 28 | +.. rst-class:: build |
| 29 | +.. container:: |
| 30 | + |
| 31 | + | - me |
| 32 | +
|
| 33 | +Why Virtual Environments? |
| 34 | +------------------------- |
| 35 | + |
| 36 | +.. rst-class:: build |
| 37 | + |
| 38 | +* You will need to install packages that aren't in the Python standard |
| 39 | + Library |
| 40 | +* You often need to install *different* versions of the *same* library for |
| 41 | + different projects |
| 42 | +* Conflicts arising from having the wrong version of a dependency installed can |
| 43 | + cause long-term nightmares |
| 44 | +* Use `pyvenv`_ ... |
| 45 | +* **Always** |
| 46 | + |
| 47 | +.. _pyvenv: https://docs.python.org/3/library/venv.html |
| 48 | + |
| 49 | +Creating a Venv |
| 50 | +--------------- |
| 51 | + |
| 52 | +Since version 3.3, Python has come with a built-in ``venv`` module. This |
| 53 | +module provides a command you can use to create virtual environments: |
| 54 | +``pyvenv`` |
| 55 | + |
| 56 | +.. rst-class:: build |
| 57 | +.. container:: |
| 58 | + |
| 59 | + The basic usage for this command is as follows: |
| 60 | + |
| 61 | + .. code-block:: bash |
| 62 | + |
| 63 | + $ pyvenv /path/to/new/environment |
| 64 | +
|
| 65 | + On Windows you'll need something a bit different: |
| 66 | + |
| 67 | + .. code-block:: posh |
| 68 | + |
| 69 | + c:\Temp>c:\Python35\python -m venv myenv |
| 70 | +
|
| 71 | + Unless you have the Python executable in your path, in which case this: |
| 72 | + |
| 73 | + .. code-block:: posh |
| 74 | + |
| 75 | + c:\Temp>python -m venv myenv |
| 76 | +
|
| 77 | +
|
| 78 | +.. nextslide:: |
| 79 | + |
| 80 | +In any of these command forms, the name of the new virtual environment |
| 81 | +(``myenv``) is arbitrary. |
| 82 | + |
| 83 | +.. rst-class:: build |
| 84 | +.. container:: |
| 85 | + |
| 86 | + I suggest that you name virtual environments to match the project for which |
| 87 | + the environment is to be used. |
| 88 | + |
| 89 | + I also suggest that you keep your virtual environments *in the same |
| 90 | + directory* as the project code you are writing. |
| 91 | + |
| 92 | +.. nextslide:: |
| 93 | + |
| 94 | +Let's make one for demonstration purposes: |
| 95 | + |
| 96 | +.. code-block:: bash |
| 97 | +
|
| 98 | + $ pyvenv demoenv |
| 99 | + $ ls demoenv |
| 100 | + bin include lib pyvenv.cfg |
| 101 | +
|
| 102 | +
|
| 103 | +.. nextslide:: What Happened? |
| 104 | + |
| 105 | +When you ran that command, a couple of things took place: |
| 106 | + |
| 107 | +.. rst-class:: build |
| 108 | + |
| 109 | +* A new directory with your requested name was created |
| 110 | +* A new Python executable was created in <ENV>/bin (<ENV>/Scripts on Windows) |
| 111 | +* The new Python was cloned from your system Python (where virtualenv was |
| 112 | + installed) |
| 113 | +* The new Python was isolated from any libraries installed in the old Python |
| 114 | +* Setuptools was installed so you have ``easy_install`` for this new python |
| 115 | +* Pip was installed so you have ``pip`` for this new python |
| 116 | + |
| 117 | +Activation |
| 118 | +---------- |
| 119 | + |
| 120 | +Every virtual environment you create contains an executable Python command. |
| 121 | + |
| 122 | +.. rst-class:: build |
| 123 | +.. container:: |
| 124 | + |
| 125 | + If you do a quick check to see which Python executable is found by your |
| 126 | + terminal, you'll see that it is not the one: |
| 127 | + |
| 128 | + .. container:: |
| 129 | + |
| 130 | + .. code-block:: bash |
| 131 | +
|
| 132 | + $ which python |
| 133 | + /usr/bin/python |
| 134 | +
|
| 135 | + in powershell: |
| 136 | + |
| 137 | + .. code-block:: posh |
| 138 | + |
| 139 | + $ gcm python |
| 140 | + ... |
| 141 | +
|
| 142 | + You can execute the new Python by explicitly pointing to it: |
| 143 | + |
| 144 | + .. code-block:: bash |
| 145 | +
|
| 146 | + $ ./demoenv/bin/python -V |
| 147 | + Python 3.5.0 |
| 148 | +
|
| 149 | +.. nextslide:: |
| 150 | + |
| 151 | +But that's tedious and hard to remember. |
| 152 | + |
| 153 | +.. rst-class:: build |
| 154 | +.. container:: |
| 155 | + |
| 156 | + Instead, ``activate`` your virtual environment using a shell command: |
| 157 | + |
| 158 | + +----------+------------+----------------------------------------+ |
| 159 | + | Platform | Shell | Activation Command | |
| 160 | + +==========+============+========================================+ |
| 161 | + | Posix | bash/zsh | ``$ source <venv>/bin/activate`` | |
| 162 | + + +------------+----------------------------------------+ |
| 163 | + | | fish | ``$ . <venv>/bin/activate.fish`` | |
| 164 | + + +------------+----------------------------------------+ |
| 165 | + | | csh/tcsh | ``$ source <venv>/bin/activate.csh`` | |
| 166 | + +----------+------------+----------------------------------------+ |
| 167 | + | Windows | cmd.exe | ``C:> <venv>/Scripts/activate.bat`` | |
| 168 | + + +------------+----------------------------------------+ |
| 169 | + | | powershell | ``PS C:> <venv>/Scripts/Activate.ps1`` | |
| 170 | + +----------+------------+----------------------------------------+ |
| 171 | + |
| 172 | +.. nextslide:: |
| 173 | + |
| 174 | +Notice that when a virtualenv is *active* you can see it in your command |
| 175 | +prompt: |
| 176 | + |
| 177 | +.. rst-class:: build |
| 178 | +.. container:: |
| 179 | + |
| 180 | + .. code-block:: bash |
| 181 | +
|
| 182 | + (demoenv)$ |
| 183 | +
|
| 184 | + So long as the virtualenv is *active* the ``python`` executable that will |
| 185 | + be used will be the new one in your ``demoenv``. |
| 186 | + |
| 187 | +Installing Packages |
| 188 | +------------------- |
| 189 | + |
| 190 | +Since ``pip`` is also installed, the ``pip`` that is used to install new |
| 191 | +software will also be the one in ``demoenv``. |
| 192 | + |
| 193 | +.. code-block:: bash |
| 194 | +
|
| 195 | + (demoenv)$ which pip |
| 196 | + /Users/cewing/demoenv/bin/pip |
| 197 | +
|
| 198 | +.. rst-class:: build |
| 199 | +.. container:: |
| 200 | + |
| 201 | + This means that using these tools to install packages will install them |
| 202 | + *into your virtual environment only* |
| 203 | + |
| 204 | + The are not installed into the system Python. |
| 205 | + |
| 206 | + Let's see this in action. |
| 207 | + |
| 208 | +.. nextslide:: |
| 209 | + |
| 210 | +We'll install a package called ``docutils`` |
| 211 | + |
| 212 | +.. rst-class:: build |
| 213 | +.. container:: |
| 214 | + |
| 215 | + It provides tools for creating documentation using ReStructuredText |
| 216 | + |
| 217 | + Install it using pip (while your virtualenv is active): |
| 218 | + |
| 219 | + .. code-block:: bash |
| 220 | +
|
| 221 | + (demoenv)$ pip install docutils |
| 222 | + Downloading/unpacking docutils |
| 223 | + Downloading docutils-0.11.tar.gz (1.6MB): 1.6MB downloaded |
| 224 | + Running setup.py (path:/Users/cewing/demoenv/build/docutils/setup.py) egg_info for package docutils |
| 225 | + ... |
| 226 | + changing mode of /Users/cewing/demoenv/bin/rst2xml.py to 755 |
| 227 | + changing mode of /Users/cewing/demoenv/bin/rstpep2html.py to 755 |
| 228 | + Successfully installed docutils |
| 229 | + Cleaning up... |
| 230 | +
|
| 231 | +.. nextslide:: |
| 232 | + |
| 233 | +And now, when we fire up our Python interpreter, the docutils package is |
| 234 | +available to us: |
| 235 | + |
| 236 | +.. code-block:: pycon |
| 237 | +
|
| 238 | + (demoenv)$ python |
| 239 | + Python 3.5.0 (default, Sep 16 2015, 10:42:55) |
| 240 | + [GCC 4.2.1 Compatible Apple LLVM 6.1.0 (clang-602.0.49)] on darwin |
| 241 | + Type "help", "copyright", "credits" or "license" for more information. |
| 242 | + >>> import docutils |
| 243 | + >>> docutils.__path__ |
| 244 | + ['/Users/cewing/projects/uwpce/training.python_web/testenvs/sess01/demoenv/lib/python3.5/site-packages/docutils'] |
| 245 | + >>> ^d |
| 246 | + (demoenv)$ |
| 247 | +
|
| 248 | +.. nextslide:: Side Effects |
| 249 | + |
| 250 | +Like some other Python libraries, the ``docutils`` package provides a number of |
| 251 | +executable scripts when it is installed. |
| 252 | + |
| 253 | +.. rst-class:: build |
| 254 | +.. container:: |
| 255 | + |
| 256 | + You can see these in the ``bin`` directory inside your virtualenv: |
| 257 | + |
| 258 | + .. code-block:: bash |
| 259 | +
|
| 260 | + (demoenv)$ ls ./demoenv/bin |
| 261 | + ... |
| 262 | + python |
| 263 | + rst2html.py |
| 264 | + rst2latex.py |
| 265 | + ... |
| 266 | +
|
| 267 | + These scripts are set up to execute using the Python with which they were |
| 268 | + built. |
| 269 | + |
| 270 | + Running these scripts *from this location* will use the Python executable |
| 271 | + in your virtualenv, *even if that virtualenv is not active*! |
| 272 | + |
| 273 | +Deactivation |
| 274 | +------------ |
| 275 | + |
| 276 | +So you've got a virtual environment created and activated so you can work with |
| 277 | +it. |
| 278 | + |
| 279 | +.. rst-class:: build |
| 280 | +.. container:: |
| 281 | + |
| 282 | + Eventually you'll need to stop working with this ``venv`` and switch |
| 283 | + to another |
| 284 | + |
| 285 | + It's a good idea to keep a separate ``venv`` for every project you |
| 286 | + work on. |
| 287 | + |
| 288 | + When a ``venv`` is active, all you have to do is use the |
| 289 | + ``deactivate`` command: |
| 290 | + |
| 291 | + .. code-block:: bash |
| 292 | +
|
| 293 | + (demoenv)$ deactivate |
| 294 | + $ which python |
| 295 | + /usr/bin/python |
| 296 | +
|
| 297 | + Note that your shell prompt returns to normal, and now the executable |
| 298 | + Python found when you check ``python`` is the system one again. |
| 299 | + |
| 300 | +Cleaning Up |
| 301 | +----------- |
| 302 | + |
| 303 | +The final advantage that ``venv`` offers you as a developer is the ability to |
| 304 | +easily remove a batch of installed Python software from your system. |
| 305 | + |
| 306 | +.. rst-class:: build |
| 307 | +.. container:: |
| 308 | + |
| 309 | + Consider a situation where you installed a library that breaks your Python |
| 310 | + (it happens) |
| 311 | + |
| 312 | + If you are working in your system Python, you now have to figure out what |
| 313 | + that package installed |
| 314 | + |
| 315 | + You have to figure out where it is |
| 316 | + |
| 317 | + And you have to go clean it out manually. |
| 318 | + |
| 319 | + With ``venv`` you simply remove the directory ``venv`` created when you |
| 320 | + started out. |
| 321 | + |
| 322 | +.. nextslide:: |
| 323 | + |
| 324 | +Let's do that with our ``demoenv``: |
| 325 | + |
| 326 | +.. rst-class:: build |
| 327 | +.. container:: |
| 328 | + |
| 329 | + .. code-block:: bash |
| 330 | +
|
| 331 | + $ rm -r demoenv |
| 332 | +
|
| 333 | + And that's it. |
| 334 | + |
| 335 | + The entire environment and all the packages you installed into it are now |
| 336 | + gone. |
| 337 | + |
| 338 | + There are no traces left to pollute your world. |
0 commit comments