Search code examples
pippipenvpython-venv

pipenv install inside virtual environment


I understand that the standard way to use pipenv install is to install outside of the virtual environment. However, this seems to be contrary to the old practice of pip install inside the virtual environment.

  1. Is there a way to install packages inside the virtual environment (venv) with pipenv?

  2. What if I pip install within the venv? Apart from not registering the install in Pipfile, what is the difference?

  3. Will pipenv know if I pip installed inside venv from outside?

Many thanks for your help.


Solution

  • question number 1

    Is there a way to install packages inside the virtual environment (venv) with pipenv?

    yes. there is a situation like so: you have a Pipfile that was generated from an old virtual env, like this one:

    [[source]]
    url = "https://pypi.org/simple"
    verify_ssl = true
    name = "pypi"
    
    [packages]
    requests = "*"
    rich = "*"
    pylint = "*"
    bs4 = "*"
    datedelta = "*"
    gtts = "*"
    keyboard = "*"
    pyperclip = "*"
    pytz = "*"
    pyttsx3 = "*"
    pydub = "*"
    speechrecognition = "*"
    scipy = "*"
    pyowm = "*"
    imageio = "*"
    opencv-python = "*"
    pyautogui = "*"
    moviepy = "*"
    selenium = "*"
    pyppeteer = "*"
    playwright = "*"
    pdfplumber = "*"
    pypdf2 = "*"
    tqdm = "*"
    ciphey = "*"
    pytesseract = "*"
    pyzbar = "*"
    
    [dev-packages]
    pytest = "*"
    
    [requires]
    python_version = "3.10"
    

    you have the project and the Pipfile, but you created a new virtual environment at the root of the project and you dont have any python packages installed, yet.

    you can install dependecies using pipenv from Pipfile:

    # assuming in are in the project root
    # and the venv is activated
    pipenv install
    

    this will install just the production packages.

    also install all packages + dev packages:

    pipenv install --dev
    

    this will install all packages from Pipfile

    question number 2

    What if I pip install within the venv? Apart from not registering the install in Pipfile, what is the difference?

    if you have a venv and if you do pip install <package>, this will install the package and its dependencies (if they are in the requirements.txt, if not you have bad luck == you have to install them manually) in the venv just the traditional way. pip doesnt take into consideration dependency conflicts.

    and thats why pipenv its coming into the game. it was designed to manage dependency conflicts and to install all required deps from by a package

    (very important) if you do install with pip the package and its dependencies will not appear in the Pipfile, everything installed with pipenv will appear in Pipfile and Pipfile.lock.

    diffs between pipfile and pipfile.lock

    • pipfile is like a pyproject.toml. it contains a list with all packages installed by the user (you, the programmer). meaning that the dependecies of a package, for example, requests, will not appear in the pipfile, they will appear int the pipfile.lock. for example certifi its a dependency of requests, it will not appear in the pipfile, but pipfile.lock. pipfile also contains the sources from where you get your packages, they could be locally, from pypi or from github
    • pipfile.lock contains metadata about the package and some hashes. it contains also every package installed and every dependency, every production package and every development package and also their hashes. basically its a json list with everything you got in your project venv

    conclusion for this question: pipenv its better and easier to use and to manage your deps for your project. its recommended. you can do whatever you want, amigo.

    question numero tres (3)

    Will pipenv know if I pip installed inside venv from outside?

    answer: No. you have to manage it, manually.

    assuming that the venv is activated and created with pipenv and a package like pytest was installed with pip install instead of pipenv install => then it would be this situation:

    a quick test in terminal

    
    # NOTE
    # this is what happens if you install in an empty project
    # pipenv creates a new venv and creates pipfile and pipfile.lock
    
    ļ„” [~/Alexzander__/programming/dev/python3/test]
    ā±  pipenv install
    Creating a virtualenv for this project...
    Pipfile: ~/Alexzander__/programming/dev/python3/test/Pipfile
    Using /usr/bin/python (3.10.1) to create virtualenv...
    ā ¼ Creating virtual environment...created virtual environment 
    
    bla bla
    
    āœ” Successfully created virtual environment!
    
    Installing dependencies from Pipfile.lock (e4eef2)...
      šŸ   ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ 0/0 ā€” 00:00:00
    To activate this project virtualenv, run pipenv shell.
    Alternatively, run a command inside the virtualenv with pipenv run.
    
    
    ļ„” [~/Alexzander__/programming/dev/python3/test]
    ā±  ls
    # the great 2 files
    ļ€– Pipfile  ļ€£ Pipfile.lock
    
    
    ļ„” [~/Alexzander__/programming/dev/python3/test]
    # activating venv
    ā±  pipenv shell
    Launching subshell in virtual environment...
     . ~/.local/share/virtualenvs/test-dG72Jjk6/bin/activate
    
    
    ļ„” [~/Alexzander__/programming/dev/python3/test]
    ā±   . ~/.local/share/virtualenvs/test-dG72Jjk6/bin/activate
    
    ī˜† (test-dG72Jjk6)
    ļ„” [~/Alexzander__/programming/dev/python3/test]
    ā±
    # now the venv is active, you can see this `test-dG72Jjk6`
    
    ī˜† (test-dG72Jjk6)
    ļ„” [~/Alexzander__/programming/dev/python3/test]
    ā±  which pip
    # pip is from current venv
    ~/.local/share/virtualenvs/test-dG72Jjk6/bin/pip
    
    ī˜† (test-dG72Jjk6)
    ļ„” [~/Alexzander__/programming/dev/python3/test]
    # installing pytest using pip instead of pipenv
    ā±  pip install pytest
    Collecting pytest ...
    
    bla bla
    
    Successfully installed attrs-21.4.0 iniconfig-1.1.1 packaging-21.3 pluggy-1.0.0 py-1.11.0 pyparsing-3.0.6 pytest-6.2.5 toml-0.10.2
    
    # see ? pytest and its dependencies. good
    
    
    ī˜† (test-dG72Jjk6)
    ļ„” [~/Alexzander__/programming/dev/python3/test]
    ā±  cat Pipfile
    
    # as you can see the `Pipfile` its empty
    
    [[source]]
    url = "https://pypi.org/simple"
    verify_ssl = true
    name = "pypi"
    
    [packages]
    # pytest should appear here  <--------------------- ####
    
    [dev-packages]
    
    [requires]
    python_version = "3.10"
    
    # and also pipfile.lock its empty
    ā±  cat Pipfile.lock
    {
        "_meta": {
            "hash": {
                "sha256": "fedbd2ab7afd84cf16f128af0619749267b62277b4cb6989ef16d4bef6e4eef2"
            },
            "pipfile-spec": 6,
            "requires": {
                "python_version": "3.10"
            },
            "sources": [
                {
                    "name": "pypi",
                    "url": "https://pypi.org/simple",
                    "verify_ssl": true
                }
            ]
        },
        "default": {},
        "develop": {}
    }
    

    now, lets install a package with pipenv install, like requests

    ā±  pipenv install requests
    Installing requests...
    Adding requests to Pipfile [packages]...
    āœ” Installation Succeeded
    Pipfile.lock (e4eef2) out of date, updating to (a290a1)...
    Locking [dev-packages] dependencies...
    Locking [packages] dependencies...
    Building requirements...
    Resolving dependencies...
    āœ” Success!
    Updated Pipfile.lock (a290a1)!
    Installing dependencies from Pipfile.lock (a290a1)...
      šŸ   ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ 0/0 ā€” 00:00:00
    
    ī˜† (test-dG72Jjk6)
    ļ„” [~/Alexzander__/programming/dev/python3/test]
    ā±  cat Pipfile
    [[source]]
    url = "https://pypi.org/simple"
    verify_ssl = true
    name = "pypi"
    
    [packages]
    requests = "*" # <---------------------------- ###
    
    [dev-packages]
    
    [requires]
    python_version = "3.10"
    

    as you can see now, requests its here and its also in pipfile.lock (i cant print that too, the answer its too long), but pytest its not here and will not be.

    Until i do this:

    ā±  pip freeze
    attrs==21.4.0
    certifi==2021.10.8
    charset-normalizer==2.0.10
    idna==3.3
    iniconfig==1.1.1
    packaging==21.3
    pluggy==1.0.0
    py==1.11.0
    pyparsing==3.0.6
    pytest==6.2.5
    requests==2.27.1
    toml==0.10.2
    urllib3==1.26.7
    
    ī˜† (test-dG72Jjk6)
    ļ„” [~/Alexzander__/programming/dev/python3/test]
    ā±  pip freeze > requirements.txt
    
    # installing packages from requirements file
    ā±  pipenv install -r requirements.txt
    Requirements file provided! Importing into Pipfile...
    Pipfile.lock (a290a1) out of date, updating to (856742)...
    Locking [dev-packages] dependencies...
    Locking [packages] dependencies...
    Building requirements...
    Resolving dependencies...
    āœ” Success!
    Updated Pipfile.lock (856742)!
    Installing dependencies from Pipfile.lock (856742)...
      šŸ   ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ā–‰ 0/0 ā€” 00:00:00
    
    
    ī˜† (test-dG72Jjk6)
    ļ„” [~/Alexzander__/programming/dev/python3/test]
    ā±  cat Pipfile
    [[source]]
    url = "https://pypi.org/simple"
    verify_ssl = true
    name = "pypi"
    
    [packages]
    requests = "==2.27.1"
    attrs = "==21.4.0"
    certifi = "==2021.10.8"
    charset-normalizer = "==2.0.10"
    idna = "==3.3"
    iniconfig = "==1.1.1"
    pluggy = "==1.0.0"
    py = "==1.11.0"
    pyparsing = "==3.0.6"
    pytest = "==6.2.5" # <----------------------------- ITS HERE :)
    toml = "==0.10.2"
    urllib3 = "==1.26.7"
    
    [dev-packages]
    
    [requires]
    python_version = "3.10"
    

    so thats how you can update the pipfile if you (accidentally) installed packages using pip install

    the conclusion for this is to use pipenv from the beginning to the end. it will manage everything.

    and thats it. now you are ready to code.