pipenv로 패키지 관리하기
Jan 22, 2020 · 7 min read



파이썬의 패키지 매니저

대부분의 프로그래밍 언어들은 자체적으로 패키지 관리 도구(package manager)를 제공하고 있습니다. 자바의 Maven, 자바스크립트의 npm처럼 파이썬에서는 pip라는 매우 간단한 패키지 관리 도구가 있는데요. 다른 언어의 패키지 매니저와 비교했을 때 부족한 부분들이 많다고 느끼실 겁니다.

일단 기본적으로 패키지 설치가 전역으로(global) 설치되기 때문에 한 컴퓨터 상에서 여러 파이썬 프로젝트에 걸쳐 작업을 하기가 힘들고, 프로젝트 별로 설치가 필요한 패키지를 정의하는 방식도 어디는 requirements.txt를 사용하고 다른데는 setup.py를 사용하는 등 표준화가 모호한 부분이 있습니다.

pipenv란?

pipenv는 파이썬에서도 패키지를 프로젝트 단위로 관리를 할 수 있도록 도와주는 고급 패키지 관리 도구입니다. 기본적으로 pip를 기반으로 동작하지만, 프로젝트 별로 격리된 가상 환경(virtual environment)과 프로젝트 단위의 패키지 관리 매커니즘을 제공합니다.

pipenv 설치

Mac 사용자라면 Homebrew를 통해 간편하게 pipenv를 터미널 상에서 설치할 수 있습니다.

$ brew install pipenv

Mac을 사용하지 않는 분들은, pip을 이용해서 전역으로 설치해서 사용하면 됩니다.

$ pip install pipenv

가상 환경 구성

먼저 pipenv로 패키지 관리를 하고 싶은 프로젝트 폴더로 이동합니다. 저는 임의로 learn-python이라는 폴더를 생성하고 그 안으로 들어갔습니다.

$ mkdir learn-python
$ cd learn-python

가상 환경에서 사용할 파이썬 버전을 --python 옵션에 명시하여 pipenv 커맨드를 실행하면 가상 환경이 만들어집니다.

$ pipenv --python 3.7
Creating a virtualenv for this project…
Pipfile: /Users/dale/learn/learn-python/Pipfile
Using /Users/dale/.pyenv/versions/3.7.6/bin/python3 (3.7.6) to create virtualenv…
⠋ Creating virtual environment...Already using interpreter /Users/dale/.pyenv/versions/3.7.6/bin/python3
Using base prefix '/Users/dale/.pyenv/versions/3.7.6'
New python executable in /Users/dale/.local/share/virtualenvs/learn-python-XBV2stdv/bin/python3
Also creating executable in /Users/dale/.local/share/virtualenvs/learn-python-XBV2stdv/bin/python
Installing setuptools, pip, wheel...
done.
Running virtualenv with interpreter /Users/dale/.pyenv/versions/3.7.6/bin/python3

✔ Successfully created virtual environment!
Virtualenv location: /Users/dale/.local/share/virtualenvs/learn-python-XBV2stdv

뿐만 아니라 프로젝트 디렉토리에 Pipfile이 생성된 것을 보실 수 있으실 겁니다. 이 Pipfile 파일이 pipenv에서 가장 핵심이 되고 중요한 부분인데요. 이 파일에는 마치 자바스크립트의 package.json또는 자바의 pom.xml처럼 프로젝트의 메타 정보가 저장됩니다.

  • Pipfile
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]

[packages]

[requires]
python_version = "3.7"

[requires] 항목에 가상 환경을 생성할 때 지정했던 파이썬 버전이 명시되어 있음을 알 수 있습니다.

참고로 다음 커맨드를 통해 해당 프로젝트에서 사용하는 가상 환경과 파이썬 인터프리터의 정확한 위치를 확인할 수 있습니다.

$ pipenv --venv
/Users/dale/.local/share/virtualenvs/learn-python-XBV2stdv
$ pipenv --py
/Users/dale/.local/share/virtualenvs/learn-python-XBV2stdv/bin/python

파이썬 실행

프로젝트의 셋업된 파이썬 인터프리터는 pipenv run 커맨드를 이용해서 간단하게 실행할 수 있습니다.

$ pipenv run python
Python 3.7.6 (default, Jan 11 2020, 16:42:53)
[Clang 11.0.0 (clang-1100.0.33.16)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.executable
'/Users/dale/.local/share/virtualenvs/learn-python-XBV2stdv/bin/python'
>>>

가상 환경 사용

venvvirtualenv을 사용하는 것과 마찬가지 방식으로 터미널에서 가상 환경을 활성화할 수 있습니다. pipenv shell 커맨드를 날리면, 쉘 프로프트 앞에 (프로젝트 폴더명)이 붙으면서 가상 환경이 활성화될 것입니다. which 커맨드를 통해 어떤 파이썬 인터프리터가 사용되는지 확인보면 가상 환경의 파이썬이 사용되고 있음을 알 수 있습니다.

$ pipenv shell
Launching subshell in virtual environment…
 . /Users/dale/.local/share/virtualenvs/learn-python-XBV2stdv/bin/activate
(learn-python) $ which python
/Users/dale/.local/share/virtualenvs/learn-python-XBV2stdv/bin/python

가상 환경에을 비활성화하려면 exit 명령어만 날려주면 됩니다. 가상 환경에서 빠져나오면 다시 원래대로 운영체제의 기본 파이썬 인터프리터를 사용하게 됩니다.

(learn-python) $ exit
$ which python
/Users/dale/.pyenv/shims/python

파이썬 가상 환경에 대해산 자세한 설명은 파이썬에서 venv로 가상 환경 사용하기을 참고 바랍니다.

혹시 어떤 연유로 가상 환경을 아예 제거해버리고 싶다면 --rm 옵션을 붙여서 pipenv를 실행하면 됩니다.

$ pipenv --rm
Removing virtualenv (/Users/dale/.local/share/virtualenvs/learn-python-XBV2stdv)

패키지 설치

이제 아무 패키지나 하나를 설치해보도록 하겠습니다. 저는 requests라는 매우 유명한 패키지를 설치해보게습니다.

$ pipenv install requests
Installing requests…
Adding requests to Pipfile's [packages]…
✔ Installation Succeeded
Pipfile.lock not found, creating…
Locking [dev-packages] dependencies…
Locking [packages] dependencies…
✔ Success!
Updated Pipfile.lock (444a6d)!
Installing dependencies from Pipfile.lock (444a6d)…
  🐍   ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 5/5 — 00:00:00
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.

패키지가 설치가 완료되면 Pipfile 파일의 [packages] 항목에 설치된 패키지가 명시됩니다.

  • Pipfile
[packages]
requests = "*"

뿐만 아니라 Pipfile.lock 피일도 생성되어 있는 것을 보실 수 있으실텐데요. 이 파일은 pipenv가 설치된 패키지의 버전과 그 패키지가 의존하는 다른 패키지들의 정확한 버전을 기억하기 위해서 자체적으로 사용한는 파일입니다. 따라서 우리가 직접 수정할 일은 없으며, 수정해서도 안 됩니다. 이렇게 pipenvPipfile.lock이라는 패키지 잠금 파일을 사용해서 Pipfile 파일에 정확한 버전이 명시되어 있지않더라도 항상 동일한 버전의 패키지를 설치할 수 있도록 해줍니다.

개발용 패키지 설치

pipenv을 사용하면 애플리케이션 실행에 필요한 일단 패키지와 개발에만 필요한 패키지를 명확히 구분해서 설치할 수 있습니다. 예를 들어, 단위 테스트를 할 때만 사용되는 pytest 패키지의 경우 다음과 같이 --dev 옵션을 줘서 개발 의존성(dev dependency)으로 설치할 수 있습니다.

$ pipenv install pytest --dev
Installing pytest…
Adding pytest to Pipfile's [dev-packages]…
✔ Installation Succeeded
Pipfile.lock (26cdc5) out of date, updating to (444a6d)…
Locking [dev-packages] dependencies…
✔ Success!
Locking [packages] dependencies…
✔ Success!
Updated Pipfile.lock (26cdc5)!
Installing dependencies from Pipfile.lock (26cdc5)…
  🐍   ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 16/16 — 0

패키지의 설치가 끝나면 Pipfile 파일의 [dev-packages] 항목에 pytest가 추가된 것을 볼 수 있습니다.

  • Pipfile
[dev-packages]
pytest = "*"

모든 패키지 한 번에 설치

pipenv는 협업 프로젝트에서 여러 개발자들이 함께 일할 때 더 빛을 발합니다. 왜냐하면, Pipfile 파일과 Pipfile.lock 파일만 있으면 누구나 동일한 가상 환경을 구성하고 동일한 버전의 패키지를 설치할 수 있기 때문입니다. 즉, 프로젝트 내 모든 개발자들은 Git 저장소에 올려둔 Pipfile 파일과 Pipfile.lock 파일은 내려받은 후에 pipenv install 커맨드 하나로 모든 패키지를 한 방에 설치할 수 있습니다.

$ pipenv install
Installing dependencies from Pipfile.lock (26cdc5)…
  🐍   ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 5/5 — 00:00:00
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.

추가로 개발 의존성으로 명시된 패키지들은 --dev 옵션을 붙여서 설치할 수 있습니다.

pipenv install --dev
Installing dependencies from Pipfile.lock (26cdc5)…
  🐍   ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 16/16 — 00:00:01
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.

그 밖에 유용한 명령어

지금까지 소개드린 기본적인 커맨드 외에도 pipenv는 몇가지 유용한 명령어를 제공합니다. 예를 들어, pipenv graph 커맨드를 날리면 프로젝트에 설치된 패키지들을 트리 구조로 시각화하여 보여줍니다.

$ pipenv graph
pytest==5.3.4
  - attrs [required: >=17.4.0, installed: 19.3.0]
  - importlib-metadata [required: >=0.12, installed: 1.4.0]
    - zipp [required: >=0.5, installed: 2.0.0]
      - more-itertools [required: Any, installed: 8.1.0]
  - more-itertools [required: >=4.0.0, installed: 8.1.0]
  - packaging [required: Any, installed: 20.0]
    - pyparsing [required: >=2.0.2, installed: 2.4.6]
    - six [required: Any, installed: 1.14.0]
  - pluggy [required: >=0.12,<1.0, installed: 0.13.1]
    - importlib-metadata [required: >=0.12, installed: 1.4.0]
      - zipp [required: >=0.5, installed: 2.0.0]
        - more-itertools [required: Any, installed: 8.1.0]
  - py [required: >=1.5.0, installed: 1.8.1]
  - wcwidth [required: Any, installed: 0.1.8]
requests==2.22.0
  - certifi [required: >=2017.4.17, installed: 2019.11.28]
  - chardet [required: >=3.0.2,<3.1.0, installed: 3.0.4]
  - idna [required: >=2.5,<2.9, installed: 2.8]
  - urllib3 [required: >=1.21.1,<1.26,!=1.25.1,!=1.25.0, installed: 1.25.8]

또한, pipenv check 커맨드를 통해 보안 취약점이 있는 패키지가 설치되어 있는지도 간단하게 체크가 가능합니다.

$ pipenv check
Checking PEP 508 requirements…
Passed!
Checking installed package safety…
All good!

마치면서

아직 초안 상태인 PEP 582을 보면 파이썬에서도 다른 언어처럼 로컬 패키지 디렉토리를 지원하는 방안이 검토되고 있습니다. 파이썬의 기본 패키지 관리 도구인 pip에서 이러한 기능을 지원되면 금상첨화이겠지만, pipenv 패키지 매니저를 사용하면 다른 언어 못지않게 효과적으로 프로젝트를 관리할 수 있으니 잘 활용하셨으면 좋겠습니다.






Engineering Blog  by Dale Seo