티스토리 뷰

파이썬 패키지 관리에 관한 좋은 포스트를 보아 영어 원문의 일부분을 한글로 옮겨 보았다. 피드백은 언제나 환영한다.

원문: https://opensource.com/article/19/4/managing-python-packages

 

Managing Python packages the right way

Don't fall victim to the perils of Python package management.

opensource.com

 

 

 

 

 

잠깐, 포스트를 읽기 전 기초 지식으로 알아야 할 것들을 썼다.

다들 아실테지만 혹시 모를 수도 있으니 써본다. 

리눅스는 유닉스 기반의 운영체제이고 우분투는 리눅스 배포판이다. 리눅스 배포판으로는 Ubuntu, CentOS, Fedora 등이 있다. 배포판마다 각자의 패키지 매니지먼트가 있는데 Ubuntu의 apt, CentOS의 Yum, Fedora의 dnf 등이 그 예이다. 아래에서는 우분투에서 사용하는 패키지 매니지먼트에 대해 잠깐 살펴보자.

Ubuntu package management

우분투 공식 문서 참고: https://ubuntu.com/server/docs/package-management

Introduction

앞서 말했듯이 우분투는 리눅스의 배포판이므로 우분투의 패키지 관리 시스템 역시 Debian GNU/Linux 배포판에서 파생됐다. 패키지 파일은 응용 프로그램 구현 시 필요한 모든 필요 파일, 메타 데이터, 지시 사항 등이 포함되어있다.

데비안 패키지의 확장자는 `.deb` 이며 보통 온라인/물리 미디어(ex CD-ROM)의 repository에 있다. 패키지는 바이너리 형태로 컴파일되어 빠른 설치가 가능하다.

Apt

우분투의 apt (Advanced Packaging Tool) 는 강력한 커맨드라인 툴로 새로운 패키지 설치, 기존 패키지 업그레이드, 패키지 리스트 업데이트의 기능을 제공한다. 커맨드라인 툴이지만 대화형으로 사용되며 비대화형으로 사용할 수 없다. apt-get 커맨드는 스크립트에서 사용해야 한다.

패키지를 설치할 때 종종 $ sudo apt update이나 $ sudo apt upgrade 등의 커맨드를 보는데 둘의 차이가 뭔지 몰랐었다. update는 패키지 인덱스를 업데이트하는 것이고 upgrade는 패키지를 최신본으로 업데이트 하는 것이었다.

Aptitude
aptitude는 apt를 텍스트 기반 프론트 엔드로 제공한다. aptitude 설치 후 터미널에서 $ aptitude 커맨드를 입력하면 아래와 같이 나온다. 업그레이드 가능한 패키지, 설치된 패키지 등의 목록을 보여준다. 신기해.

 

dpkg

dpkg는 데비안 기반 시스템을 위한 패키지 매니저다. 설치, 삭제, 패키지 빌드는 가능하지만 자동 다운로드나 종속 패키지를 설치하지는 않는다. dpkg에 추가 기능을 덧붙인 패키지 매니저가 apt와 aptitude이다.

 

 

 

 

여기부터 원문이다.

Python Package Index(PyPI)는 라이브러리 및 애플리케이션 배열을 인덱싱한다. (주: 인덱스를 이용해 패키지를 찾고 설치하므로) 그러나 이 때 종종 발생하는 문제로 권한 누락, 호환되지 않는 라이브러리 종속성이 있다. 

Installing applications system-wide

pip은 파이썬에서 사실상 패키지 관리자이다. (주:PyPI 에서 사용하는 패키지 인스톨러가 pip 이기 때문이다.) pip은 먼저 종속성을 검사한 뒤 시스템이 이미 설치되어 있는지 확인한다. 없다면 자동으로 설치도 한다. 모든 종속 패키지가 만족되면 요청받은 패키지를 설치한다. 이 작업들은 기본적으로 운영 체제에 종속된 단일 위치의 시스템에 모두 설치된다. 

 

글로벌 설치의 문제는 주어진 Python 인터프리터에서 한 번에 단일 버전의 패키지만 설치할 수 있다는 것이다. 이게 왜 문제냐면 이 패키지가 다른 여러개의 패키지들에 종속인경우, 각각 요구하는 버전이 다를 수 있기 때문이다. 그럼 현재는 잘 작동하더라도 이후 라이브러리나 application이 업데이트 되면 작동이 안될 수 있다.

 

다른 잠재적인 문제는 대부분의 Unix-like 계열 배포판은 파이썬 패키지를 빌트인 패키지 매니저(dnf, apt, pacman, brew 등)로 관리한다는 점이다. 그리고 이들 몇 개는 사용자가 쓸 수 없는 위치에 패키지를 설치한다.

$ python3.7 -m pip install pytest
Collecting pytest
Downloading...
[...]
Installing collected packages: atomicwrites, pluggy, py, more-itertools, pytest
Could not install packages due to an EnvironmentError: [Error 13] Permission denied:
'/usr/lib/python3.7/site-packages/site-packages/atomicwrites-x.y.z.dist-info'
Consider using '--user' option or check the permissions.

물론 이는 sudo 커맨드를 통해 해결할 수 있다. 하지만 이는 리눅스 배포판의 패키지 관리자가 소유한 위치에 파이썬 패키지를 설치하게 되므로 내부 데이터베이스와 설치의 일관성이 없어진다. 이렇게 되면 이후 패키지 관리자를 사용하여 설치나 삭제 시 문제가 발생할 수 있다.

 

예를 들어, 배포판 패키지 관리자인 pacman 으로 다시 pytest를 설치해보자. 이번에는 잘 설치되었다. 그런데 보면 설치된 경로가 아까와 다른 것 처럼 보인다.

$ sudo pacman -S community/python-pytest
resolving dependencies...
looking for conflicting packages...
[...]
python-py: /usr/lib/site-packages/py/_pycache_/_metainfo.cpython-37.pyc exists in filesystem
python-py: /usr/lib/site-packages/py/_pycache_/_builtin.cpython-37.pyc exists in filesystem
python-py: /usr/lib/site-packages/py/_pycache_/_error.cpython-37.pyc exists in filesystem

또다른 잠재적 문제는 OS가 Pyhton을 시스템 툴로 사용할 수 있고 시스템 패키지 매니저 외부에서 파이썬 패키지를 쉽게 수정할 수 있다는 점이다. 당연히 시스템이 작동하지 않을 수 있으며 백업에서 복원하거나 전체 재설치만이 유일한 해결방법이다.

 

 

 

sudo pip install: A bad idea

sudo pip install이 안 좋은 이유는 또있는데 그전에 먼저 파이썬 라이브러리와 어플리케이션이 어떻게 패키지화되는지 보자.

 

대부분의 라이브러리들과 어플리케이션들은 빌드 시스템으로 setuptools을 사용한다. setuptools는 프로젝트의 루트에 setup.py 파일을 정의해야하는데 여기에는 패키지의 메타데이터, 빌드 프로세스에 대한 파이썬 코드 등이 정의되어있다. 패키지 설치 시 이 파일은 설치 작업과 함께 시스템 조사, 패키지 빌드 등의 작업을 한다.

 

루트 권한으로 setup.py를 실행하면 악성 코드나 버그에 쉽게 노출된다. PyPI 는 누구나 패키지를 업로드 할 수 있고 그것이 치명적인지 검토하지 않기때문이다. 관련해서 최근 파이썬 소프트웨어 재단에서 발표한 내용인데 참고하실분은 보시라. https://pyfound.blogspot.com/2018/12/upcoming-pypi-improvements-for-2019.html

 

보안 문제를 제처두고서라도 sudo pip install 로는 종속성 문제를 해결할 수 없다.

 

이제 조금 더 나은 대안들을 보자.

 

 

 

OS package managers

OS 패키지 매니저들도 파이썬 패키지를 설치할 수 있다. 문제는 우리가 pip, apt, dnf, pacman등을 사용해야하는가 이다.

답은: 때에 따라 다르다.

 

pip은 일반적으로 PyPI에서 패키지를 직접 설치하는데 사용되며 파이썬 패키지 저자들은 보통 여기에 업로드한다. 그러나 대부분의 패키지 관리자는 PyPI를 사용하지 않고 GitHub 등에서 소스코드를 가져와 필요한 경우 패치, 테스트, 릴리즈 합니다. 각각 장단점이 있는데,

- 기본 패키지 매니저에 의해 관리되는 소프트웨어가 일반적으로 더 안정적이고 주어진 플랫폼에서 더 잘 작동한다. (항상 그런건 아니다.)

- PyPI에 비해 제공되는 패키지가 훨씬 적다.

- 업데이트가 느리고 패키지 매니저가 이전 버전을 제공하는 경우가 많다.

 

만약 원하는 패키지가 있고 패키지 매니저의 버전에 상관없다면, 패키지 매니저는 안전하고 편한 파이썬 패키지 설치를 제공할 것이다. 또한 이 패키지들은 system-wide 하기 때문에 이 시스템을 쓰는 모든 유저에게 사용가능하다. (=같은 버전의 패키지를 쓸 것이다). 물론 이는 우리가 필요권한을 갖고 있을 경우에 해당한다.

 

원하는 패키지가 없거나, 있으나 너무 이전 버전이거나, 설치 시 필요권한이 없다면 pip을 사용할 수 있다.

 

(주: os 패키지 매니저에서도 파이썬 패키지를 설치 할 수 있었다! Ubuntu – Software Packages in "focal", Subsection python 우분투 공식 홈페이지에서 지원하는 패키지를 볼 수 있다. 링크는 20.04 LTS에서 파이썬관 연관된 패키지 목록인데 생각보다 꽤 많아서 놀랐다. pandas나 sklearn도 지원한다. $ sudo apt-get install python3-pandas)

 

 

User scheme installations

pip은 파이썬2.6부터 패키지를 사용자 소유 위치에 설치하도록 하는 user scheme 모드를 지원한다. 리눅스에서는 보통 ~/.local 위치다. ~/.local/bin을 PATH에 추가하면 파이썬 툴과 스크립트를 쉽게 사용할 수 있고 루트 권한없이 관리할 수 있다.

$ python3.7 -m pip install --user black
Collecting black
 Using cached
[...]
Installing collected packages: click, toml, black
 The scripts black and blackd are installed in '/home/tux/.local/bin' which is not on PATH.
 Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed black-x.y click-x.y toml-x.y.z

 

하지만 역시 종속성 문제는 해결할 수 없다.

 

 

 

Enter virtual environments

가상환경은 같은 시스템의 격리된 공간에 파이썬 패키지를 설치한다. user scheme과 같은 이점이 있으며 다른 애플리케이션과 종속성을 공유하지 않는 자체 포함 파이썬 설치도 가능하다. (It allows the creation of self-contained Python installaionts).  Virtualenv는 파이썬 바이너리와 패키지 관리를 위한 필수 도구(setuptools, pip, wheel을), 자체 self-contained 파이썬 설치를 포함하는 디렉토리를 생성한다.

 

 

 

Creating virtual environments

파이썬 3.3부터 venv 패키지가 표준 라이브러리로 추가되었다. 그래서 따로 가상환경을 만들기위해 설치할 필요가 없어졌다. $ python3 -m venv ENV_NAME 으로 새 가상 공간을 만들 수 있다.

 

새 공간을 생성 후 활성화하기 위해 bin 디렉토리에서 activate 스크립트를 sourcing 해야한다. activation 스크립트는 새로운 서브쉘을 만들어서 PATH환경변수에 bin 디렉토리를 추가한다. 그러면 이 서브쉘은 글로벌하게 시스템에 설치된 툴이 아닌 해당 위치에 설치된 것들을 사용한다.

$ python3.7 -m venv test-env
$ . ./test-env/bin/activate
(test-env) $

이후 모든 커맨드는 가상 공간안에서 이루어진다. 패키지 설치 후 PATHPYTHONPATH 같은 어떠한 환경 변수도 건드릴 필요가 없다. 끝에는 deactivate 하자.

 

가상 환경은 activation script 없이 사용할 수 있다. venv에 설치된 스크립트는 가상 환경 내에서 Python 인터프리터를 사용하기 위해 shebang 줄을 다시 작성한다. 이렇게하면 스크립트의 전체 경로를 사용하여 시스템의 어느 곳에서나 스크립트를 실행할 수 있다.

 

자주 사용하는 가상환경을 PATH환경변수에 추가하면 유용하다. 프로젝트 별로 환경이 다르고 라이브러리 종속성이 다르기 때문에 가상 환경은 파이썬 개발에서 아주 흔히 쓰인다.

 

 

 

What about Conda?

Conda 는 Anaconda 에서 만든 패키지 관리 툴로 환경 생성, 관리, 패키지 설치를 쉽게해준다. 단점은 pip보다 지원되는 패키지 수가 적다.

 

 

요약!

A recipe for successful package management

  • Never run sudo pip install.
  • If you want to make a package available to all users of the machine, you have the right permissions, and the package is available, then use your distribution's package manager (apt, yum, pacman, brew, etc.).
  • If you don't have root permissions or the OS package manager doesn't have the package you need, use pip install --user and add the user installation directory to the PATH environment variable.
  • If you want multiple versions of the same library to coexist, to do Python development, or just to isolate dependencies for any other reason, use virtual environments.
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함