|  | 
|  | 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