Skip to content

Instantly share code, notes, and snippets.

@jsgoller1
Created July 17, 2020 18:35
Show Gist options
  • Select an option

  • Save jsgoller1/694e1a646ea7cf363c289c5f1029f5a6 to your computer and use it in GitHub Desktop.

Select an option

Save jsgoller1/694e1a646ea7cf363c289c5f1029f5a6 to your computer and use it in GitHub Desktop.

Revisions

  1. jsgoller1 created this gist Jul 17, 2020.
    131 changes: 131 additions & 0 deletions venvs.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,131 @@
    Virtual environments ("venvs") make setting up Python projects easy, especially for projects multiple people work on.
    First, we need to create the venv:

    ```bash
    joshua.goller @ joshua-goller ~/Code/skip-example
    └─ $ ▶ python3 -m venv ./venv
    joshua.goller @ joshua-goller ~/Code/skip-example
    └─ $ ▶ ls
    venv
    ```

    As you can see, running the command created a folder `venv` containing the virtual environment. This folder contains
    a basic Python3 interpreter and packages, and is ready to go. To get started, we activate it as follows:
    ```
    joshua.goller @ joshua-goller ~/Code/skip-example
    └─ $ ▶ source venv/bin/activate
    (venv) joshua.goller @ joshua-goller ~/Code/skip-example
    └─ $ ▶
    ```

    Notice how my shell is now prefixed with `(venv)` - this his how venvs signal that they are currently active. I can exit the virtual environment as follows:
    ```
    (venv) joshua.goller @ joshua-goller ~/Code/skip-example
    └─ $ ▶ deactivate
    joshua.goller @ joshua-goller ~/Code/skip-example
    └─ $ ▶
    ```

    Notice what happens with `which python` when I'm in the venv vs not:
    ```
    joshua.goller @ joshua-goller ~/Code/skip-example
    └─ $ ▶ which python
    /usr/bin/python
    joshua.goller @ joshua-goller ~/Code/skip-example
    └─ $ ▶ source venv/bin/activate
    (venv) joshua.goller @ joshua-goller ~/Code/skip-example
    └─ $ ▶ which python
    /home/joshua.goller/Code/skip-example/venv/bin/python
    ```

    As you can see, the default Python setup the shell uses is changed; as such, any `python` commands you run while
    in the venv will use the venv's python installation. Let's now install the `requests` library to the venv (you may
    be prompted to run `pip install --upgrade pip`, which you should do but isn't required here):
    ```
    (venv) joshua.goller @ joshua-goller ~/Code/skip-example
    └─ $ ▶ pip3 install requests
    Collecting requests
    Downloading https://files.pythonhosted.org/packages/45/1e/0c169c6a5381e241ba7404532c16a21d86ab872c9bed8bdcd4c423954103/requests-2.24.0-py2.py3-none-any.whl (61kB)
    |████████████████████████████████| 71kB 2.2MB/s
    Collecting urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 (from requests)
    Using cached https://files.pythonhosted.org/packages/e1/e5/df302e8017440f111c11cc41a6b432838672f5a70aa29227bf58149dc72f/urllib3-1.25.9-py2.py3-none-any.whl
    Collecting idna<3,>=2.5 (from requests)
    Downloading https://files.pythonhosted.org/packages/a2/38/928ddce2273eaa564f6f50de919327bf3a00f091b5baba8dfa9460f3a8a8/idna-2.10-py2.py3-none-any.whl (58kB)
    |████████████████████████████████| 61kB 9.7MB/s
    Collecting certifi>=2017.4.17 (from requests)
    Downloading https://files.pythonhosted.org/packages/5e/c4/6c4fe722df5343c33226f0b4e0bb042e4dc13483228b4718baf286f86d87/certifi-2020.6.20-py2.py3-none-any.whl (156kB)
    |████████████████████████████████| 163kB 17.3MB/s
    Collecting chardet<4,>=3.0.2 (from requests)
    Using cached https://files.pythonhosted.org/packages/bc/a9/01ffebfb562e4274b6487b4bb1ddec7ca55ec7510b22e4c51f14098443b8/chardet-3.0.4-py2.py3-none-any.whl
    Installing collected packages: urllib3, idna, certifi, chardet, requests
    Successfully installed certifi-2020.6.20 chardet-3.0.4 idna-2.10 requests-2.24.0 urllib3-1.25.9
    ```
    As you can see, we've now installed the requests package and can use it from our venv's python:
    ```
    (venv) joshua.goller @ joshua-goller ~/Code/skip-example
    └─ $ ▶ python3
    Python 3.7.7 (default, Dec 27 2004, 00:00:16)
    [GCC 10.1.0] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import requests
    >>> requests
    <module 'requests' from '/home/joshua.goller/Code/skip-example/venv/lib/python3.7/site-packages/requests/__init__.py'>
    ```
    Watch what happens if we try to do the same thing from the default system python:
    ```
    (venv) joshua.goller @ joshua-goller ~/Code/skip-example
    └─ $ ▶ deactivate
    joshua.goller @ joshua-goller ~/Code/skip-example
    └─ $ ▶ python3
    Python 3.7.7 (default, Dec 27 2004, 00:00:16)
    [GCC 10.1.0] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import requests
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    ModuleNotFoundError: No module named 'requests'
    >>>
    ```

    So as you can see, venvs let you manage your setup in a self contained way. One last tip - to see all the packages currently
    installed in your venv, do the following:
    ```
    (venv) joshua.goller @ joshua-goller ~/Code/skip-example
    └─ $ ▶ pip freeze
    certifi==2020.6.20
    chardet==3.0.4
    idna==2.10
    requests==2.24.0
    urllib3==1.25.9
    ```

    This is highly useful, because then you can save it to a file, and use that file to install every package you need
    instead of having to install them one by one (the `>` character redirects the output of `pip freeze` to a file, which is created):
    ```
    (venv) joshua.goller @ joshua-goller ~/Code/skip-example
    └─ $ ▶ pip freeze > requirements.txt
    (venv) joshua.goller @ joshua-goller ~/Code/skip-example
    └─ $ ▶ cat requirements.txt
    certifi==2020.6.20
    chardet==3.0.4
    idna==2.10
    requests==2.24.0
    urllib3==1.25.9
    ```
    Then, someone else (including you, if you want to set the project up on a new machine) can come by on their system with that file and do this:
    ```
    (some-other-venv) joshua.goller @ joshua-goller ~/Code/skip-example
    └─ $ ▶ pip install -r requirements.txt
    Collecting certifi==2020.6.20 (from -r requirements.txt (line 1))
    Using cached https://files.pythonhosted.org/packages/5e/c4/6c4fe722df5343c33226f0b4e0bb042e4dc13483228b4718baf286f86d87/certifi-2020.6.20-py2.py3-none-any.whl
    Collecting chardet==3.0.4 (from -r requirements.txt (line 2))
    Using cached https://files.pythonhosted.org/packages/bc/a9/01ffebfb562e4274b6487b4bb1ddec7ca55ec7510b22e4c51f14098443b8/chardet-3.0.4-py2.py3-none-any.whl
    Collecting idna==2.10 (from -r requirements.txt (line 3))
    Using cached https://files.pythonhosted.org/packages/a2/38/928ddce2273eaa564f6f50de919327bf3a00f091b5baba8dfa9460f3a8a8/idna-2.10-py2.py3-none-any.whl
    Collecting requests==2.24.0 (from -r requirements.txt (line 4))
    Using cached https://files.pythonhosted.org/packages/45/1e/0c169c6a5381e241ba7404532c16a21d86ab872c9bed8bdcd4c423954103/requests-2.24.0-py2.py3-none-any.whl
    Collecting urllib3==1.25.9 (from -r requirements.txt (line 5))
    Using cached https://files.pythonhosted.org/packages/e1/e5/df302e8017440f111c11cc41a6b432838672f5a70aa29227bf58149dc72f/urllib3-1.25.9-py2.py3-none-any.whl
    Installing collected packages: certifi, chardet, idna, urllib3, requests
    Successfully installed certifi-2020.6.20 chardet-3.0.4 idna-2.10 requests-2.24.0 urllib3-1.25.9
    ```